<?php

namespace App\Web\Model;

use App\Service\DbIndex;
use App\Service\Dict;
use App\Service\DictConstant;
use App\Web\Facades\UserAuth;
use App\Web\Model\RabbitMQ\ResumeUpdate;
use App\Web\Model\Resume as ResumeModel;
use App\Web\Model\User as UserModel;
use App\Web\Model\Coin as CoinModel;
use App\Service\ExternalAPI\VApi;
use EchoPHP\Facades\Db;
use EchoPHP\Facades\Log;
use EchoPHP\File\UploadedFile;
use EchoPHP\Validator\Validator;
use App\Web\Model\Attach as AttachModel;
use Exception;
use Ramsey\Uuid\Uuid;
use RuntimeException;
use App\Command\ResumeParsing\FileToResume;

class Resume extends Model {
    private $dict;

    public function __construct() {
        $this->dict = new Dict();
    }

    /**
     * 根据简历id，获取简历信息
     * @param array $resumeIds
     * @param string|true $oprId 为true时具备全部权限，为空不具备敏感信息查看权限
     * @param string $channel e:英文，否则空为中文
     * @return array
     * @throws Exception
     */
    public function getResumeInfo(array $resumeIds, $oprId = '', $channel = '') {
        if (empty($resumeIds)) {
            return array();
        }

        //$resumeIds['300022254'] = '';
        //$resumeIds['2501981135'] = '';
        //$resumeIds['301809654'] = '';    // accountid:51911892

        $resumeIds_JY = $resumeIds_51 = $resumeInfo = array();
        $resumeIds_JY = $resumeIds;

        $resumeInfo = $this->getRpoResumeInfo($resumeIds);
        if (!empty($resumeInfo) && count($resumeInfo) > 0) {
            foreach ($resumeIds as $key => $item) {
                if (isset($resumeInfo[$key])) {
                    $resumeIds[$key] = $resumeInfo[$key];
                    unset($resumeIds_JY[$key]);
                }
            }
        }

        if (!empty($resumeIds_JY)) {
            $resumeJYInfo = $this->getJYResumeInfo($resumeIds_JY);
            if (!empty($resumeJYInfo) && count($resumeJYInfo) > 0) {
                foreach ($resumeIds as $key => $item) {
                    if (!isset($resumeJYInfo[$key])) {
                        continue;
                    }
                    /*
                    $tmpResume = array();
                    $tmpResume['accountid'] = $resumeJYInfo[$key]['accountid'];
                    $tmpResume['resumeid'] = $resumeJYInfo[$key]['resumeid'];
                    $resumeIds_51[$key] = $tmpResume;
                    continue;
                    */

                    //24亿以上为精英网导入简历
                    if ($key >= 2400000000) {
                        if (isset($resumeJYInfo[$key])) {
                            $resumeIds[$key] = $resumeJYInfo[$key];
                        }
                    } else {
                        $tmpResume = array();
                        $tmpResume['accountid'] = $resumeJYInfo[$key]['accountid'];
                        $tmpResume['resumeid'] = $resumeJYInfo[$key]['resumeid'];
                        $resumeIds_51[$key] = $tmpResume;
                    }
                }
            }
        }

        //$resumeIds_51['301809654'] = array('accountid' => 51911892, 'resumeid' => 301809654);
        //$resumeIds_51['300022254'] = array('accountid' => 49985251, 'resumeid' => 300022254);

        if (!empty($resumeIds_51)) {
            $resume51Info = $this->get51ResumeInfo($resumeIds_51, $channel);
            if (!empty($resume51Info) && count($resume51Info) > 0) {
                foreach ($resumeIds as $key => $item) {
                    if (isset($resume51Info[$key])) {
                        $resumeIds[$key] = $resume51Info[$key];
                    }
                }
            }
        }
        $resumeIds = array_filter($resumeIds);
        $tmpResumeIds = array_keys($resumeIds);

        //没有下载的简历，核心字段屏蔽
        if (!empty($oprId) && !empty($tmpResumeIds)) {
            if ($oprId === true) {
                $alreadyDownList = $tmpResumeIds;
            } else {
                $alreadyDownList = $this->getDownloadResumeId($oprId, $tmpResumeIds, true);
            }
            $this->hideNotDownloadedFields($resumeIds, $alreadyDownList);
        }

        //简历渠道来源
        $resumePlatDict = [];
        $resumePlatConfig = config('app.global_resumeplat');
        if (is_file($resumePlatConfig)) {
            $resumePlatDict = include $resumePlatConfig;
        }

        foreach ($resumeIds as $key => &$resumeInfo) {
            //全局替换文本中无法显示的?
            $resumeInfoTmp = json_encode($resumeInfo);
            $resumeInfoTmp = str_replace('?', '●', $resumeInfoTmp);
            $resumeInfo = json_decode($resumeInfoTmp, true);
            $resumeInfo['idcard'] = ''; //身份证隐私

            $resumeInfo['updatedateshow'] = '';
            if (!empty($resumeInfo['updatedate'])) {
                $resumeInfo['updatedateshow'] = date('Y-m-d', strtotime($resumeInfo['updatedate']));
            }

            //简历渠道来源
            if (isset($resumePlatDict[$resumeInfo['platform'] . '_' . $resumeInfo['source']])) {
                $resumeInfo['platname'] = $resumePlatDict[$resumeInfo['platform'] . '_' . $resumeInfo['source']];
            } else if (isset($resumePlatDict[$resumeInfo['platform']])) {
                $resumeInfo['platname'] = $resumePlatDict[$resumeInfo['platform']] . ($resumeInfo['source'] == '' ? '' : '_' . $resumeInfo['source']);
            } else if (!isset($resumePlatDict[$resumeInfo['platform']])) {
                $resumeInfo['platname'] = '未知渠道:' . $resumeInfo['platform'] . ($resumeInfo['source'] == '' ? '' : '_' . $resumeInfo['source']);
            }

            $resumeInfo['age'] = '';
            if (!$this->isEmptyDate($resumeInfo['birthday'])) {
                $tmpTime = strtotime($resumeInfo['birthday']);
                $resumeInfo['birthdayoriginal'] = date('Y-m-d', $tmpTime);
                $age = date('Y') - date('Y', $tmpTime);
                if ($age < 18 || $age > 60) {
                    $resumeInfo['age'] = '';
                    $resumeInfo['birthday'] = '';
                } else {
                    $resumeInfo['age'] = $age;
                    $resumeInfo['birthday'] = date($resumeInfo['language'] == 'en' ? 'Y' : 'Y年', $tmpTime);
                }

            } else {
                $resumeInfo['birthday'] = '';
            }

            //逆过程 TranslateHelper::translateWorkyear()，须保持一致
            $resumeInfo['workyearnum'] = '';
            if (empty($resumeInfo['workyear'])) {
                if ($resumeInfo['workyear'] == 0) {
                    $resumeInfo['workyearnum'] = $resumeInfo['language'] == 'en' ? 'No experience' : '暂无工作经验';
                }
            } else if (is_numeric($resumeInfo['workyear'])) {
                $workyear = date('Y') - $resumeInfo['workyear'];
                if ($workyear >= 0 && $workyear <= 60) {
                    if ($workyear == 0) {
                        $workyear = 1;   //本年的也算一年
                    }
                    $resumeInfo['workyearnum'] = $workyear . ($resumeInfo['language'] == 'en' ? ($workyear > 1 ? ' Years' : ' Year') : '年工作经验');
                }
            }

            if (empty($resumeInfo['salary'])) {
                if (empty($resumeInfo['currentsalaryinfo']['total']) && !empty($resumeInfo['salaryfrom'])) {
                    if (empty($resumeInfo['salaryto'])) {
                        $resumeInfo['salaryto'] = $resumeInfo['salaryfrom'];
                    }
                    $resumeInfo['currentsalaryinfo']['total'] = $resumeInfo['salary'] =
                        $this->renderSalary('万元', round($resumeInfo['salaryfrom'] * 13 / 10000, 1), round($resumeInfo['salaryto'] * 13 / 10000, 1));
                }
                $resumeInfo['salary'] = !empty($resumeInfo['currentsalaryinfo']['total']) ? $resumeInfo['currentsalaryinfo']['total'] . '/年' : '';
            }
            if (empty($resumeInfo['expectsalary']) && !empty($resumeInfo['expectsalaryfrom'])) {
                if (empty($resumeInfo['expectsalaryto'])) {
                    $resumeInfo['expectsalaryto'] = $resumeInfo['expectsalaryfrom'];
                }
                $resumeInfo['expectsalaryinfo'] = [
                    'num' => $this->renderSalary('', round($resumeInfo['expectsalaryfrom'], 1), round($resumeInfo['expectsalaryto'], 1)),
                    "unit" => '元/月'
                ];
                $resumeInfo['expectsalary'] = $resumeInfo['expectsalaryinfo']['text'] = $resumeInfo['expectsalaryinfo']['num'] . ' ' . $resumeInfo['expectsalaryinfo']['unit'];
            }
            $attributes = [
                'gender' => [DictConstant::DD_GENDER, ''],
                'hukou' => [DictConstant::DD_CITY_COUNTY, ''],
                'area' => [DictConstant::DD_CITY_COUNTY, ''],
                'expectarea' => [DictConstant::DD_CITY_COUNTY, ''],
                'politic' => [DictConstant::DD_POLITICS, ''],
                'degree' => [DictConstant::DD_DEGREE, ''],
                'major' => [DictConstant::DD_MAJOR, ''],
                'married' => [DictConstant::DD_MARRIAGE, ''],
                'workindustry' => [DictConstant::DD_INDUSTRY, ''],
                'position' => [DictConstant::DD_FUNCTYPE, ''],
                'current_situation' => [DictConstant::DD_CURRENT_SITUATION, ''],
                'seektype' => [DictConstant::DD_JOB_TERM, ''],
                'entrytime' => [DictConstant::DD_NEW_JOB_ENTRY_TIME, '']
            ];
            $this->dict->setLang($resumeInfo['language'] == 'en' ? DictConstant::LANG_EN : DictConstant::LANG_ZH);
            $this->dict->singRowTrans($resumeInfo, $attributes, true, ',', ' ');
            $this->dict->setLang(DictConstant::LANG_ZH);
            $resumeInfo['position'] = trim($resumeInfo['position'] . ' ' . $resumeInfo['position_input']);
            if (is_array($resumeInfo['educationinfo']) && count($resumeInfo['educationinfo'])) {
                $topDegree = -1;
                foreach ($resumeInfo['educationinfo'] as &$edu) {
                    if (empty($edu['degree_code']) || !is_numeric($edu['degree_code'])) {
                        if (!empty($edu['degree'])) {
                            $degreeDict = $this->dict->all(DictConstant::DD_DEGREE);
                            if (!empty($degreeDict)) {
                                foreach ($degreeDict as $key => $value) {
                                    if (trim($edu['degree']) == $value) {
                                        $edu['degree_code'] = $key;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (empty($edu['major_code']) || !is_numeric($edu['major_code'])) {
                        if (!empty($edu['major'])) {
                            $majorDict = include(ROOT_PATH . '/app/Command/ResumeParsing/Service/Dict/majorDict.php');
                            if (!empty($majorDict)) {
                                $tmp = strtoupper($edu['major']);
                                $tmp = preg_replace('/[^\x{4e00}-\x{9fff}A-Za-z1-9]+/u', '', $tmp);
                                foreach ($majorDict as $key => $value) {
                                    if (trim($tmp) == $key) {
                                        $edu['major_code'] = $value;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    $degree = empty($edu['degree_code']) || !is_numeric($edu['degree_code']) ? 0 : intval($edu['degree_code']);

                    if ($degree > $topDegree) {
                        $topDegree = $degree;
                        $resumeInfo['school'] = $edu['school'] ?? '';
                        $resumeInfo['major'] = $edu['major'] ?? '';
                        $resumeInfo['major_code'] = $edu['major_code'] ?? '';
                        $resumeInfo['degree'] = $edu['degree'] ?? '';
                        $resumeInfo['degree_code'] = $edu['degree_code'] ?? '';
                    }
                }
            }

            //最近工作
            $resumeInfo['recentcompany'] = '';
            $resumeInfo['recentduty'] = '';
            $resumeInfo['recentworkindustry'] = '';
            $resumeInfo['recentworktimespan'] = '';
            if (is_array($resumeInfo['workinfo']) && count($resumeInfo['workinfo']) > 0) {
                $resumeInfo['recentcompany'] = $resumeInfo['workinfo'][0]['company'];
                $resumeInfo['recentduty'] = trim($resumeInfo['workinfo'][0]['duty']);
                $resumeInfo['recentworkindustry'] = $resumeInfo['workinfo'][0]['workindustry'];
                $resumeInfo['recentworktimespan'] = $resumeInfo['workinfo'][0]['time']['timespan'] ?? '';
            }

            //是否显示最近工作项目
            $resumeInfo['hasrecentwork'] = 1;
            if (trim($resumeInfo['degree'] . $resumeInfo['major'] . $resumeInfo['school']) == ''
                && trim($resumeInfo['recentcompany'] . $resumeInfo['recentduty'] . $resumeInfo['recentworkindustry'] . $resumeInfo['recentworktimespan']) == ''
            ) {
                $resumeInfo['hasrecentwork'] = 0;
            }

            //是否显示目前年收入项目
            $resumeInfo['hascurrentsalary'] = 1;

            if (!isset($resumeInfo['currentsalaryinfo']) || !is_array($resumeInfo['currentsalaryinfo']) || count($resumeInfo['currentsalaryinfo']) < 1) {
                $resumeInfo['hascurrentsalary'] = 0;
            } else {
                if (empty($resumeInfo['currentsalaryinfo']['total'])
                    && empty($resumeInfo['currentsalaryinfo']['basesalary'])
                    && empty($resumeInfo['currentsalaryinfo']['bonus'])
                    && empty($resumeInfo['currentsalaryinfo']['allowance'])
                    && empty($resumeInfo['currentsalaryinfo']['stock'])) {
                    $resumeInfo['hascurrentsalary'] = 0;
                }
            }

            //是否显示求职意向项目
            $strExpectsalaryTmp = '';
            if (isset($resumeInfo['expectsalaryinfo']) && is_array($resumeInfo['expectsalaryinfo']) && count($resumeInfo['expectsalaryinfo']) > 0) {
                $strExpectsalaryTmp = $resumeInfo['expectsalaryinfo']['text'];
            }
            $resumeInfo['hasjobintention'] = 1;
            if (empty($strExpectsalaryTmp)
                && empty($resumeInfo['position'])
                && empty($resumeInfo['expectarea'])
                && empty($resumeInfo['workindustry'])
                && empty($resumeInfo['seektype'])
                && empty($resumeInfo['selfintro'])
            ) {
                $resumeInfo['hasjobintention'] = 0;
            }

            //是否显示工作经验项目
            $resumeInfo['hasworkinfo'] = 1;
            if (!isset($resumeInfo['workinfo']) || !is_array($resumeInfo['workinfo']) || count($resumeInfo['workinfo']) < 1) {
                $resumeInfo['hasworkinfo'] = 0;
            }

            //是否显示项目经验项目
            $resumeInfo['hasprojectinfo'] = 1;
            if (!isset($resumeInfo['projectinfo']) || !is_array($resumeInfo['projectinfo']) || count($resumeInfo['projectinfo']) < 1) {
                $resumeInfo['hasprojectinfo'] = 0;
            }

            //是否显示教育经历项目
            $resumeInfo['haseducationinfo'] = 1;
            if (!isset($resumeInfo['educationinfo']) || !is_array($resumeInfo['educationinfo']) || count($resumeInfo['educationinfo']) < 1) {
                $resumeInfo['haseducationinfo'] = 0;
            }

            //是否显示在校情况项目
            $resumeInfo['hasschoolinfo'] = 1;
            if (!isset($resumeInfo['schoolaward']) || !is_array($resumeInfo['schoolaward']) || count($resumeInfo['schoolaward']) < 1) {
                if (!isset($resumeInfo['schooljob']) || !is_array($resumeInfo['schooljob']) || count($resumeInfo['schooljob']) < 1) {
                    $resumeInfo['hasschoolinfo'] = 0;
                }
            }

            //是否显示技能特长项目
            $resumeInfo['hasskillinfo'] = 1;
            if (!isset($resumeInfo['itskill']) || !is_array($resumeInfo['itskill']) || count($resumeInfo['itskill']) < 1) {
                if (!isset($resumeInfo['certification']) || !is_array($resumeInfo['certification']) || count($resumeInfo['certification']) < 1) {
                    if (!isset($resumeInfo['train']) || !is_array($resumeInfo['train']) || count($resumeInfo['train']) < 1) {
                        $resumeInfo['hasskillinfo'] = 0;
                    }
                }
            }

            //简历未下载时不显示附加信息(附件,其他)
            if (empty($resumeInfo['isdownload'])) {
                $resumeInfo['attachment'] = array();
                $resumeInfo['others'] = array();
            }

            //是否显示附件项目
            $resumeInfo['hasattachinfo'] = 1;
            if (!isset($resumeInfo['attachment']) || !is_array($resumeInfo['attachment']) || count($resumeInfo['attachment']) < 1) {
                $resumeInfo['hasattachinfo'] = 0;
            }

            //是否显示其他项目
            $resumeInfo['hasothersinfo'] = 1;
            if (!isset($resumeInfo['others']) || !is_array($resumeInfo['others']) || count($resumeInfo['others']) < 1) {
                $resumeInfo['hasothersinfo'] = 0;
            }

            if (empty($resumeInfo['position'])) $resumeInfo['position'] = $resumeInfo['career'];
        }

        return $resumeIds;
    }

    /**
     * 获取简单简历详情，找简历列表页用
     * @param array $resumeIds
     * @param int $oprId
     */
    public function getSimpleResumeInfo(array $resumeIds, $oprId = 0, $channel = '') {
        //获取51job简历或者rpo上传简历中学校等信息
        return $this->getResumeInfo($resumeIds, $oprId, $channel);
    }

    /*
     * 调用51job简历json接口表
     * $resumeIds['300022254'] = array('accountid' => 49985251, 'resumeid' => 300022254);
     */
    public function get51ResumeInfo(array $resumeIds, $channel = '') {
        $resultList = $resumeList = array();
        if (empty($resumeIds)) {
            return $resultList;
        }
        $vapi = new VApi();
        foreach ($resumeIds as $key => $item) {
            $resume = $vapi->getResumeContent($item['accountid'], $item['resumeid']);

            if (1 == 0) {
                $time = explode(' ', microtime());
                $fileName = $item['resumeid'] . '_' . date('Y-m-d_H-i-s', $time[1]) . '_' . $time[0] . '.json';
                file_put_contents($fileName, json_encode($resume, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR));
            }

            if (!isset($resume['accountinfo'])) {
                continue;
            }

            $resumeList[$key] = $this->resume51ToArr($resume, $channel);

            //$resumeList[$key]['logo'] = $vapi->getResumeAvatar($item['accountid'], $item['resumeid']);
        }

        if (empty($resumeList) || count($resumeList) < 1) {
            return $resultList;
        }

        //保持查询条件的顺序
        foreach ($resumeIds as $key => $item) {
            if (isset($resumeList[$key])) {
                $resultList[$item['resumeid']] = $resumeList[$key];
            }
        }

        return $resultList;
        //echo var_export($resultList, true);
    }

    private function getResumeTemplate($debug = false) {
        $template = array();
        $templateString = $debug ? '【未定义】' : '';
        $stringFields = ['resumeid', 'source', 'platform', 'innerid', 'innerupdatetime', 'cname', 'gender', 'phone', 'email', 'birthday', 'workyear', 'area',
            'expectarea', 'salaryfrom', 'salaryto', 'degree', 'major', 'position', 'workindustry', 'school', 'nation', 'idcard', 'politic', 'age', 'hukou',
            'career', 'married', 'nofocuse', 'skillinfo', 'awardinfo', 'otherinfo', 'selfintro', 'creator', 'updator', 'createdate', 'updatedate', 'status',
            'profile', 'current_situation', 'seektype', 'entrytime', 'resumekey', 'hasheadpath', 'address', 'height', 'zipcode', 'homepage',
            'idcard', 'idtype', 'idcard_verifystatus', 'othercontacts', 'contacttype'];
        foreach ($stringFields as $field) {
            $template[$field] = $templateString;
        }
        $arrayFields = ['workinfo', 'projectinfo', 'educationinfo', 'schoolaward', 'itskill', 'train', 'certification', 'schooljob', 'others'];
        foreach ($arrayFields as $field) {
            $template[$field] = [];
        }
        $template['language'] = 'cn';
        $template['currentsalaryinfo'] = [
            'total' => $templateString,
            "basesalary" => $templateString,
            "bonus" => $templateString,
            "allowance" => $templateString,
            "stock" => $templateString
        ];
        $template['expectsalaryinfo'] = [
            'from' => $templateString,
            "to" => $templateString,
            "unit" => $templateString,
            'ratio' => 1,
            "text" => $templateString
        ];
        return $template;
    }

    /*
     * 51job简历处理
     */
    public function resume51ToArr($resume, $channel = '') {
        static $salaryRatioMap = [
            "4" => 1 / 13,
            "1" => 1,
            "3" => 22,
            "2" => 22 * 8,
        ];
        static $salaryUnitMap_cn = [
            "4" => '元/年',
            "1" => '元/月',
            "3" => '元/天',
            "2" => '元/小时',
        ];
        static $salaryUnitMap_en = [
            "4" => 'Year',
            "1" => 'Month',
            "3" => 'Day',
            "2" => 'Hour',
        ];
        $tmpResume = $this->getResumeTemplate();
        $tmpResume['language'] = $channel == 'e' ? 'en' : 'cn';
        $tmpResume['resumeid'] = $resume["resumeid"];
        $tmpResume['accountid'] = $resume["accountid"];
        $tmpResume['source'] = $resume['addtype'];    //0-正常简历，9-粘贴简历
        $tmpResume['platform'] = '51job';      //jingying,51job,rpo
        $tmpResume['hasheadpath'] = '';
        $tmpResume['hasen'] = trim($resume['accountinfo']["ename"] . $resume['accountinfo']["efirstname"]) == '' ? '' : '1'; //是否有英文简历
        $tmpResume['innerid'] = $resume["resumeid"];
        $tmpResume['innerupdatetime'] = $resume["updatetime"] ?? $resume['accountinfo']["updatetime"];
        if (!empty($tmpResume['innerupdatetime'])) {
            $tmpResume['innerupdatetime'] = date('Y-m-d H:i:s', $tmpResume['innerupdatetime']);
        }
        $tmpResume['cname'] = $tmpResume['language'] == 'en' ? $resume['accountinfo']["ename"] . ' ' . $resume['accountinfo']["efirstname"] : $resume['accountinfo']["cname"] ?? '';
        $tmpResume['gender'] = $resume['accountinfo']["sex"] ?? '';
        $tmpResume['phone'] = $resume['accountinfo']["mobilephone"] ?? '';
        $tmpResume['email'] = $resume['accountinfo']["email"] ?? '';
        $tmpResume['birthday'] = $resume['accountinfo']["birthday"] ?? '';
        $tmpResume['workyear'] = $resume['accountinfo']["workyear"] ?? '';
        $tmpResume['area'] = $resume['accountinfo']["area"] ?? '';
        $tmpResume['expectarea'] = $resume['baseinfo']["expectarea"] ?? '';
        $tmpResume['entrytime'] = $resume['baseinfo']["entrytime"] ?? '';
        $tmpResume['resumekey'] = $resume['baseinfo']["resumekey"] ?? '';
        $tmpResume['address'] = $tmpResume['language'] == 'en' ? $resume['accountinfo']["eaddress"] ?? '' : $resume['accountinfo']["caddress"] ?? '';
        $tmpResume['height'] = $resume['accountinfo']["stature"] ?? '';
        $tmpResume['zipcode'] = $resume['accountinfo']["zipcode"] ?? '';
        $tmpResume['homepage'] = $resume['accountinfo']["homepage"] ?? '';
        $tmpResume['idcard'] = $resume['accountinfo']["idcard"] ?? '';
        $tmpResume['idtype'] = $resume['accountinfo']["idtype"] ?? '';
        $tmpResume['idcard_verifystatus'] = $resume['accountinfo']["idcard_verifystatus"] ?? '';
        $tmpResume['othercontacts'] = $resume['accountinfo']["othercontacts"] ?? '';
        $tmpResume['contacttype'] = $resume['accountinfo']["contacttype"] ?? '';

        $this->dict->setLang($tmpResume['language'] == 'en' ? DictConstant::LANG_EN : DictConstant::LANG_ZH);
        $attributes = [
            'idtype' => [DictConstant::DD_ID_TYPE, ''],
            'contacttype' => [DictConstant::DD_CONTACT_TYPE, ''],
        ];
        $this->dict->singRowTrans($tmpResume, $attributes, true);
        //$salaryRatio = $salaryRatioMap[$resume['baseinfo']["salarytype"] ?? 1] ?? 1;
        //$tmpResume['expectsalaryfrom'] = $tmpResume['expectsalaryto'] = !empty($resume['baseinfo']["expectsalary"]) && is_numeric($resume['baseinfo']["expectsalary"]) ? $resume['baseinfo']["expectsalary"] * $salaryRatio : '';
        $tmpResume['expectsalary'] = '';
        $salaryUnitMap = $tmpResume['language'] == 'en' ? $salaryUnitMap_en : $salaryUnitMap_cn;
        if (!empty($resume['baseinfo']["salarytype"])) {
            $tmpResume['expectsalaryinfo'] = [
                'num' => $resume['baseinfo']["inputsalary"],
                "unit" => $salaryUnitMap[$resume['baseinfo']["salarytype"] ?? 1] ?? '元/月'
            ];
            //salarytype：月薪1;年薪4
            if (in_array($resume['baseinfo']["salarytype"], [1, 4])) {
                //yearsalary_str有内容说明是使用的非自定义薪资格式
                if (!empty($resume['baseinfo']["yearsalary_str"]) && !empty($resume['baseinfo']["expectsalary"])) {
                    if ($resume['baseinfo']["salarytype"] == 1) {
                        //$tmpResume['expectsalaryinfo']['num'] = $this->dict->trans(DictConstant::DD_MONTHLY_SALARY, $resume['baseinfo']["expectsalary"]);
                        $tmpResume['expectsalaryinfo']['num'] = $resume['baseinfo']["monthsalary_str"];
                    } elseif ($resume['baseinfo']["salarytype"] == 4) {
                        //$tmpResume['expectsalaryinfo']['num'] = $this->dict->trans(DictConstant::DD_ANNUAL_SALARY, $resume['baseinfo']["expectsalary"]);
                        $tmpResume['expectsalaryinfo']['num'] = $resume['baseinfo']["yearsalary_str"];
                    }
                }
            }

            $tmpResume['expectsalary'] = $tmpResume['expectsalaryinfo']['text'] = ($tmpResume['language'] == 'en' ? '¥' : '') . $tmpResume['expectsalaryinfo']['num'] . ' ' . $tmpResume['expectsalaryinfo']['unit'];
        }

        $unit = "";
        $unit2 = " 万元";
        if ($tmpResume['language'] == 'en') {
            $unit = "￥";
            $unit2 = " x10K";
        }
        $tmpResume['currentsalaryinfo'] = [
            "total" => !empty($resume['accountinfo']["inputsalary"]) ? $unit . $resume['accountinfo']["inputsalary"] . $unit2 : '',
            "basesalary" => !empty($resume['accountinfo']["basesalary"]) ? $unit . $resume['accountinfo']["basesalary"] . $unit2 : '',
            "bonus" => !empty($resume['accountinfo']["bonus"]) ? $unit . $resume['accountinfo']["bonus"] . $unit2 : '',
            "allowance" => !empty($resume['accountinfo']["allowance"]) ? $unit . $resume['accountinfo']["allowance"] . $unit2 : '',
            "stock" => !empty($resume['accountinfo']["stock"]) ? $unit . $resume['accountinfo']["stock"] . $unit2 : ''];
        $tmpResume['degree'] = $resume['baseinfo']["topdegree"] ?? '';
        $tmpResume['major'] = $resume['baseinfo']["topmajor"] ?? '';
        $tmpResume['position'] = !empty($resume['baseinfo']["expectfunc"]) ? $resume['baseinfo']["expectfunc"] : ($resume['baseinfo']["topfunctype"] ?? '');
        $tmpResume['position_input'] = $tmpResume['language'] == 'en' ? $resume['baseinfo']["eexpectposition"] : $resume['baseinfo']["cexpectposition"] ?? '';
        $tmpResume['workindustry'] = $resume['baseinfo']["expectindustry"] ?? '';
        $tmpResume['seektype'] = $resume['baseinfo']["seektype"] ?? '';
        $tmpResume['school'] = '';
        $tmpResume['nation'] = '';
        $tmpResume['idcard'] = isset($resume['accountinfo']["idtype"]) && $resume['accountinfo']["idtype"] == '0' ? $resume['accountinfo']["idcard"] : '';
        $tmpResume['politic'] = $resume['accountinfo']["politics_status"] ?? '';
        $tmpResume['age'] = '';
        $tmpResume['hukou'] = $resume['accountinfo']["hukou"] ?? '';
        $tmpResume['career'] = '';
        $tmpResume['married'] = $resume['accountinfo']["marriage"] ?? '';
        $tmpResume['nofocuse'] = '';
        $tmpResume['skillinfo'] = '';
        $tmpResume['awardinfo'] = '';
        $tmpResume['otherinfo'] = '';
        $tmpResume['selfintro'] = $tmpResume['language'] == 'en' ? $resume['baseinfo']["eselfintro"] : $resume['baseinfo']["cselfintro"] ?? '';
        $tmpResume['creator'] = '';
        $tmpResume['updator'] = '';
        $tmpResume['createdate'] = '';
        $tmpResume['updatedate'] = $resume["updatetime"] ?? $resume['accountinfo']["updatetime"];
        if (!empty($tmpResume['updatedate'])) {
            $tmpResume['updatedate'] = date('Y-m-d H:i:s', $tmpResume['updatedate']);
        }
        $tmpResume['status'] = '';
        $tmpResume['profile'] = '';
        $tmpResume['workinfo'] = [];
        $resumeBlocks = $tmpResume['language'] == 'en' ? $resume['e'] : $resume['c'];
        if (isset($resumeBlocks['work']) && is_array($resumeBlocks['work'])) {
            foreach ($resumeBlocks['work'] as $item) {
                $tmpItem = [];
                $tmpItem['starttime'] = $item['timefrom'];
                $tmpItem['endtime'] = $item['timeto'];
                $tmpItem['company'] = $item['ccompname'];
                $tmpItem['workindustry'] = $item['workindustry'];
                $tmpItem['duty'] = trim($item['cdepartment'] . ' ' . $item['cposition']);
                $tmpItem['department'] = $item['cdepartment'];
                $tmpItem['rawduty'] = $item['cposition'];
                $tmpItem['salary'] = '';
                $tmpItem['content'] = $item['cworkdescribe'];
                $tmpItem['workdescribe'] = $item['cworkdescribe'];
                $tmpItem['score'] = $item['cscore'];
                $tmpItem['isoverseas'] = $item['isoverseas'];
                $tmpItem['leavereason'] = $item['cleavereason'];
                $tmpItem['companysize'] = $item['companysize'];
                $tmpItem['companytype'] = $item['companytype'];
                $tmpItem['reportboss'] = $item['creportboss'];
                $tmpItem['reportperson'] = $item['reportperson'];
                $tmpItem['workfunc'] = $item['workfunc'];
                $tmpItem['worktype'] = $item['worktype'];
                $attributes = [
                    'workindustry' => [DictConstant::DD_INDUSTRY, ''],
                    'companytype' => [DictConstant::DD_COMPANY_TYPE, ''],
                    'companysize' => [DictConstant::DD_COMPANY_SIZE, ''],
                    'workfunc' => [DictConstant::DD_FUNCTYPE, ''],
                    'worktype' => [DictConstant::DD_JOB_TERM, ''],
                ];
                $this->dict->rowTrans($tmpItem, $attributes, true);

                $tmpResume['workinfo'][] = $tmpItem;
            }
            $this->formatTimespanData($tmpResume['workinfo'], true, $tmpResume['language']);
        }

        $tmpResume['projectinfo'] = [];
        if (isset($resumeBlocks['project']) && is_array($resumeBlocks['project'])) {
            foreach ($resumeBlocks['project'] as $item) {
                $tmpItem = array();
                $tmpItem ['starttime'] = $item['timefrom'];
                $tmpItem ['endtime'] = $item['timeto'];
                $tmpItem ['company'] = $item['ccompname'];
                $tmpItem ['project'] = $item['cprojectname'];
                $tmpItem ['duty'] = '';
                $tmpItem ['content'] = $item['cdescribe'];
                $tmpItem ['describe'] = $item['cdescribe'];
                $tmpItem ['function'] = $item['cfunction'];

                $tmpResume['projectinfo'][] = $tmpItem;
            }
            $this->formatTimespanData($tmpResume['projectinfo'], true, $tmpResume['language']);
        }
        $tmpResume['educationinfo'] = [];
        if (isset($resumeBlocks['education']) && is_array($resumeBlocks['education'])) {
            foreach ($resumeBlocks['education'] as $item) {
                $tmpItem = array();
                $tmpItem ['starttime'] = $item['timefrom'];
                $tmpItem ['endtime'] = $item['timeto'];
                $tmpItem ['school'] = $item['cschoolname'];
                $tmpItem ['major'] = $item['major'];
                if (empty($item['major'])) {
                    $tmpItem ['major'] = $item['cmajordes'];
                }
                $tmpItem ['degree'] = $item['degree'];
                $tmpItem ['content'] = $item['cdescribe'];
                if (!empty($item['degree'])) {
                    if ($tmpItem['degree'] >= 8) {
                        $tmpItem['degree']++;
                    } elseif ($item['degree'] == 7 && $item['ismba'] == 1) {
                        $tmpItem ['degree'] = 8;
                    }
                }
                $attributes = [
                    'major' => [DictConstant::DD_MAJOR, ''],
                    'degree' => [DictConstant::DD_DEGREE, ''],
                ];
                $this->dict->rowTrans($tmpItem, $attributes, true, ',', ',', function ($key, $value) {
                    if ($key == 'major') return strlen($value) <= 6 && !preg_match('/[\x{4e00}-\x{9fff}A-Za-z]/u', $value);   //存在非数字则不翻译
                    return true;
                });
                $tmpItem ['isoverseas'] = $item['isoverseas'];

                $tmpResume['educationinfo'][] = $tmpItem;
            }
            $this->formatTimespanData($tmpResume['educationinfo'], true, $tmpResume['language']);
        }

        $tmpResume['schoolaward'] = [];
        if (isset($resumeBlocks['schoolaward']) && is_array($resumeBlocks['schoolaward'])) {
            $tmpResume['schoolaward'] = $resumeBlocks['schoolaward'];
            $this->formatTimespanData($tmpResume['schoolaward'], true, $tmpResume['language']);
            foreach ($tmpResume['schoolaward'] as $item) {
                $tmpResume['awardinfo'] .= "\r\n" . $this->renderTime($item['bonustime']) . ' ' . $item['cbonusname'] . ' ' . $item['cbonusclass'];
            }
            $tmpResume['awardinfo'] = trim($tmpResume['awardinfo']);
        }

        $tmpResume['itskill'] = [];
        if (isset($resumeBlocks['itskill']) && is_array($resumeBlocks['itskill'])) {
            $tmpResume['itskill'] = $resumeBlocks['itskill'];
            $styleName = ['精通' => '', '熟练' => 'sl', '良好' => 'lh', '一般' => 'yb'];
            if ($tmpResume['language'] == 'en') {
                $styleName = ['Average' => 'yb', 'Good' => 'lh', 'Advanced' => 'sl', 'Expert' => ''];
            }
            foreach ($tmpResume['itskill'] as &$skillitem) {
                $attributes = [
                    'ittype' => [DictConstant::DD_SKILL, ''],
                    'ability' => [DictConstant::DD_SKILL_LEVEL, ''],
                ];
                $this->dict->rowTrans($skillitem, $attributes, true);
                $skillitem['stylename'] = isset($styleName[$skillitem['ability']]) ? $styleName[$skillitem['ability']] : '';
                $skillitem['skilltext'] = !empty($skillitem['skillsname']) ? $skillitem['skillsname'] : $skillitem['ittype'];

                $tmpResume['skillinfo'] .= "\r\n" . $skillitem['skilltext'] . ' ' . $skillitem['ability'];
            }
            $tmpResume['skillinfo'] = trim($tmpResume['skillinfo']);
        }

        $tmpResume['train'] = [];
        if (isset($resumeBlocks['train']) && is_array($resumeBlocks['train']) && count($resumeBlocks['train'])) {
            $tmpResume['train'] = $resumeBlocks['train'];
            $this->formatTimespanData($tmpResume['train'], true, $tmpResume['language']);
            $tmpResume['otherinfo'] .= "\r\n\r\n培训情况：";
            foreach ($tmpResume['train'] as $item) {
                $tmpResume['otherinfo'] .= "\r\n" . $this->renderTime($item['timefrom'], $item['timeto']) . ' ' . $item['ctrainname'] . ' ' .
                    $item['ctrainplace'] . ' ' . $item['ctrainlesson'] . (!empty($item['cdescribe']) ? "\r\n" . trim($item['cdescribe']) : '');
            }
            $tmpResume['otherinfo'] = trim($tmpResume['otherinfo']);
        }

        $tmpResume['certification'] = [];
        if (isset($resumeBlocks['certification']) && is_array($resumeBlocks['certification']) && count($resumeBlocks['certification'])) {
            $tmpResume['certification'] = $resumeBlocks['certification'];
            $this->formatTimespanData($tmpResume['certification'], true, $tmpResume['language']);
            $tmpResume['otherinfo'] .= "\r\n\r\n所获证书：";
            foreach ($tmpResume['certification'] as $key => $item) {
                $attributes = [
                    'certlist' => [DictConstant::DD_CERTIFICATION, ''],
                ];
                $this->dict->singRowTrans($item, $attributes, true);
                $tmpResume['certification'][$key]['certname'] = !empty($item['certname']) ? $item['certname'] : $item['certlist'];
                $tmpResume['otherinfo'] .= "\r\n" . $this->renderTime($item['getdate']) . ' ' .
                    (!empty($item['certname']) ? $item['certname'] : $item['certlist']) . (!empty($item['score']) ? ' ' . $item['score'] : '');  //TODO: $item['verifystatus']
            }
            $tmpResume['otherinfo'] = trim($tmpResume['otherinfo']);
        }

        $tmpResume['schooljob'] = [];
        if (isset($resumeBlocks['schooljob']) && is_array($resumeBlocks['schooljob']) && count($resumeBlocks['schooljob'])) {
            $tmpResume['schooljob'] = $resumeBlocks['schooljob'];
            $this->formatTimespanData($tmpResume['schooljob'], true, $tmpResume['language']);
            $tmpResume['otherinfo'] .= "\r\n\r\n校内职位：";
            foreach ($tmpResume['schooljob'] as $item) {
                $tmpResume['otherinfo'] .= "\r\n" . $this->renderTime($item['timefrom'], $item['timeto']) . ' ' .
                    $item['cname'] . (!empty($item['cdescribe']) ? "\r\n" . trim($item['cdescribe']) : '');
            }
            $tmpResume['otherinfo'] = trim($tmpResume['otherinfo']);
        }

        $tmpResume['attachment'] = [];
        if (isset($resumeBlocks['attachment']) && is_array($resumeBlocks['attachment'])) {
            $tmpResume['attachment'] = $resumeBlocks['attachment'];
        }

        $tmpResume['others'] = [];

        if (isset($resumeBlocks['others']) && is_array($resumeBlocks['others']) && count($resumeBlocks['others'])) {
            if ($resume['addtype'] == 9) {
                $tmpStr = '';
                foreach ($resumeBlocks['others'] as $item) {
                    $tmpStr .= !empty($item['describe']) ? "\r\n" . trim($item['describe']) : '';
                }
                $tmpResume['profile'] = $tmpStr != '' ? trim($tmpResume['profile'] . "\r\n" . $tmpStr) : '';
            } else {
                $tmpResume['others'] = $resumeBlocks['others'];
                $this->formatTimespanData($tmpResume['others'], true, $tmpResume['language']);
                $tmpResume['otherinfo'] .= "\r\n\r\n其他信息：";
                foreach ($tmpResume['others'] as &$item) {
                    if ($item['inforname'] == '') {
                        $item['inforname'] = $this->dict->trans(DictConstant::DD_OTHER_INFO_TYPE, $item['inforlist'], $item['inforname']);
                    }
                    $tmpResume['otherinfo'] .= "\r\n" . $item['inforname'] .
                        (!empty($item['describe']) ? "\r\n" . trim($item['describe']) : '');
                }
                $tmpResume['otherinfo'] = trim($tmpResume['otherinfo']);
            }
        }
        $tmpResume['current_situation'] = $resume['accountinfo']['current_situation'];

        $pregfind = array('/href\s*=\s*(\"|\')(.*?)(\"|\')/i',
            '/target\s*=\s*(\"|\')(.*?)(\"|\')/i',
            '/<script.*>.*<\/script>/siU',
            '/on(mousewheel|mouseover|click|load|onload|submit|focus|blur)\s*=\s*"[^"]*"/i');
        $pregreplace = array(' href="javascript:return false;" ', ' ', ' ', ' ');
        $tmpResume['profile'] = preg_replace($pregfind, $pregreplace, $tmpResume['profile']);

        $this->dict->setLang(DictConstant::LANG_ZH);
        return $tmpResume;
    }


    /*
     * 查询s_manager表
     */
    public function getJYResumeInfo(array $resumeIds) {
        $resultList = $resumeList = array();
        if (empty($resumeIds)) {
            return $resultList;
        }
        $var = array();
        $placeTag = $this->arrAppand($var, $resumeIds);
        if ($placeTag == "") {
            return $resultList;
        }
        $columnNme = "managerid,username51job,accountid51job,relationaccid,userid51job,headpath,cname,email,mobilephone,emailstatus,
                     division,company,workindustry,gender,privatestatus,status,lastupdate,dbid,createdate,isfinishinfo,area,mobilestatus,
                     position,source,islock,isblacklist,expectarea,workyear,school,major,degree,schoolcode,agenttype,birthday,funtype,
                     expsalary,cursalary,mkx_merge_userid,mkx_cardid,cmajordes,companyhis,orgexpsalary,
                     orgcursalary,isdestory,currsalaryfrom,currsalaryto,expsalaryfrom,expsalaryto,cexpectposition,eexpectposition,
                     profile";
        $sql = 'select ' . $columnNme . ' from s_manager where userid51job in (' . $placeTag . ') and status=?';
        $var[] = '01';

        $resumeJYList = Db::connect('jyrpo_oracle')->select($sql, $var);

        if (empty($resumeJYList) || count($resumeJYList) < 1) {
            return $resultList;
        }

        foreach ($resumeJYList as $key => $item) {
            $tmpResume = $this->getResumeTemplate();
            $tmpResume['managerid'] = $item['managerid'];
            $tmpResume['accountid'] = $item['relationaccid'] != '' ? $item['relationaccid'] : $item['accountid51job'];
            $tmpResume['resumeid'] = $item['userid51job'];
            $tmpResume['source'] = $item['source'];   //1-精英网 2-51job 3-ios 4-android 5-谷露 9-其他 8-简历导入 7-脉可寻导入御用精英
            $tmpResume['platform'] = 'jingying';      //jingying,51job,rpo
            $tmpResume['hasheadpath'] = '';
            $tmpResume['hasen'] = '';                 //是否有英文简历
            $tmpResume['innerid'] = $item['userid51job'];
            $tmpResume['innerupdatetime'] = $item['lastupdate'];
            $tmpResume['cname'] = $item['cname'];
            $tmpResume['gender'] = $item['gender'];
            $tmpResume['phone'] = $item['mobilephone'];
            $tmpResume['email'] = $item['email'];
            $tmpResume['birthday'] = $item['birthday'];
            $tmpResume['workyear'] = $item['workyear'];
            $tmpResume['area'] = $item['area'];
            $tmpResume['expectarea'] = $item['expectarea'];
            $tmpResume['salaryfrom'] = $item['currsalaryfrom'];
            $tmpResume['salaryto'] = $item['currsalaryto'];
            $tmpResume['expectsalaryfrom'] = $item['expsalaryfrom'];
            $tmpResume['expectsalaryto'] = $item['expsalaryto'];
            $tmpResume['degree'] = $item['degree'];
            $tmpResume['major'] = $item['major'];
            $tmpResume['position'] = '';
            $tmpResume['resumekey'] = '';
            $tmpResume['workindustry'] = $item['workindustry'];
            $tmpResume['school'] = $item['school'];
            $tmpResume['nation'] = '';
            $tmpResume['idcard'] = '';
            $tmpResume['politic'] = '';
            $tmpResume['age'] = '';
            $tmpResume['hukou'] = '';
            $tmpResume['career'] = '';
            $tmpResume['married'] = '';
            $tmpResume['nofocuse'] = '';
            $tmpResume['skillinfo'] = '';
            $tmpResume['awardinfo'] = '';
            $tmpResume['otherinfo'] = '';
            $tmpResume['selfintro'] = '';
            $tmpResume['creator'] = '';
            $tmpResume['updator'] = '';
            $tmpResume['createdate'] = $item['createdate'];
            $tmpResume['updatedate'] = $item['lastupdate'];
            $tmpResume['status'] = $item['status'];
            $tmpResume['profile'] = isset($item['profile']) ? $item['profile'] : '';
            $tmpResume['current_situation'] = '';
            $tmpResume['position_input'] = $item['position'];
            $resumeList[$item['userid51job']] = $tmpResume;
        }

        $sectionArr = ['workinfo', 'projectinfo', 'educationinfo', 'schoolaward', 'train', 'certification', 'schooljob', 'others'];
        //保持查询条件的顺序
        foreach ($resumeIds as $key => $item) {
            if (isset($resumeList[$key])) {
                foreach ($sectionArr as $section) {
                    $this->formatTimespanData($resumeList[$key][$section]);
                }
                $resultList[$key] = $resumeList[$key];
            }
        }

        return $resultList;
        //echo var_export($resumeList, true);
    }

    /*
     * 查询rpo mysql RpoResume表
     */
    public function getRpoResumeInfo(array $resumeIds) {
        $resultList = array();
        if (empty($resumeIds)) {
            return $resultList;
        }
        $var = array();
        $placeTag = $this->arrAppand($var, $resumeIds);
        if ($placeTag == "") {
            return $resultList;
        }

        $columnNme = "resumeid,source,innerid,innerupdatetime,cname,gender,nation,idcard,politic,phone,email,age,
                     birthday,workyear,hukou,area,expectarea,salaryfrom,salaryto,expectsalaryfrom,expectsalaryto,degree,
                     major,position,workindustry,career,married,school,nofocuse,skillinfo,awardinfo,selfintro,otherinfo,
                     hasworkinfo,hasprojectinfo,haseducationinfo,creator,createdate,updator,updatedate,status,
                     jobterm as seektype,situation as current_situation,entrytime,headpath";
        $sql = 'select ' . $columnNme . ' from RpoResume where resumeid in(' . $placeTag . ') and status=?';
        $var[] = '01';
        $resumeList = Db::select($sql, $var);

        //echo var_export($resumeIds, true);
        if (empty($resumeList) || count($resumeList) < 1) {
            return $resultList;
        }

        $resumeList_tmp = array();
        foreach ($resumeList as $key => $resume) {
            $resume['platform'] = 'rpo';          //jingying,51job,rpo
            $resume['hasen'] = '';                //是否有英文简历
            $resume['position_input'] = $resume['position'];
            $resume['position'] = '';
            $resume['resumekey'] = '';
            $resume['hasheadpath'] = empty($resume['headpath']) ? '0' : '1';

            if (!empty($resume['nofocuse'])) {
                $resume['others'][] = ['inforid' => '', 'inforlist' => '', 'key' => 'nofocuse', 'inforname' => '勿推企业', 'describe' => $resume['nofocuse']];
            }

            if (!empty($resume['skillinfo'])) {
                $resume['others'][] = ['inforid' => '', 'inforlist' => '', 'key' => 'skillinfo', 'inforname' => '技能特长', 'describe' => $resume['skillinfo']];
            }

            if (!empty($resume['awardinfo'])) {
                $resume['others'][] = ['inforid' => '', 'inforlist' => '', 'key' => 'awardinfo', 'inforname' => '奖项荣誉', 'describe' => $resume['awardinfo']];
            }

            if (!empty($resume['otherinfo'])) {
                $resume['others'][] = ['inforid' => '', 'inforlist' => '', 'key' => 'otherinfo', 'inforname' => '其他信息', 'describe' => $resume['otherinfo']];
            }

            $resumeList_tmp[$resume['resumeid']] = $resume;
        }

        //保持查询条件的顺序
        foreach ($resumeIds as $key => $item) {
            if (isset($resumeList_tmp[$key])) {
                $resultList[$key] = $resumeList_tmp[$key];
            }
        }

        $workInfoList = $this->getResumeWorkInfo(array_keys($resumeIds));
        foreach ($workInfoList as $resumeId=>$item){
            if (isset($resultList[$resumeId])) $resultList[$resumeId]['workinfo'] = $item;
        }

        $columnNme = "id,resumeid,starttime,endtime,company,duty,project,content";
        $orderByStr = "order by resumeid,IF(starttime='0000-00-00 00:00:00','9999-01-01',starttime) desc,
                                         IF(endtime='0000-00-00 00:00:00','9999-01-01',endtime) desc,id";
        $sql = 'select ' . $columnNme . ' from ResumeProject where resumeid in(' . $placeTag . ') and status=? ' . $orderByStr;
        $workList = Db::select($sql, $var);
        if (!empty($workList) && count($workList) > 0) {
            foreach ($workList as $key => &$item) {
                $item['function'] = '';
                if (isset($resultList[$item['resumeid']])) $resultList[$item['resumeid']]['projectinfo'][] = $item;
            }
        }

        $columnNme = "id,resumeid,starttime,endtime,school,major,degree,major_code,degree_code,content";
        $orderByStr = "order by resumeid,IF(starttime='0000-00-00 00:00:00','9999-01-01',starttime) desc,
                                         IF(endtime='0000-00-00 00:00:00','9999-01-01',endtime) desc,id";
        $sql = 'select ' . $columnNme . ' from ResumeEdu where resumeid in(' . $placeTag . ') and status=? ' . $orderByStr;
        $workList = Db::select($sql, $var);
        if (!empty($workList) && count($workList) > 0) {
            foreach ($workList as $key => $item) {
                $item ['isoverseas'] = 0;

                if ($item['major_code'] != '') {
                    $item['major'] = $item['major_code'];
                    unset($item['major_code']);
                    $attributes = [
                        'major' => [DictConstant::DD_MAJOR, ''],
                    ];
                    $this->dict->rowTrans($item, $attributes, true);
                }

                if ($item['degree_code'] != '') {
                    $item['degree'] = $item['degree_code'];
                    unset($item['degree_code']);
                    $attributes = [
                        'degree' => [DictConstant::DD_DEGREE, ''],
                    ];
                    $this->dict->rowTrans($item, $attributes, true);
                }
                if (isset($resultList[$item['resumeid']])) $resultList[$item['resumeid']]['educationinfo'][] = $item;
            }

        }
        $template = $this->getResumeTemplate();
        $sectionArr = ['workinfo', 'projectinfo', 'educationinfo', 'schoolaward', 'train', 'certification', 'schooljob', 'others'];
        if (!empty($resultList) && count($resultList) > 0) {
            foreach ($resultList as $resumeId => $resumeInfo) {
                foreach ($template as $key => $value) {
                    if (!isset($resumeInfo[$key])) $resumeInfo[$key] = $value;
                }
                foreach ($sectionArr as $section) {
                    $this->formatTimespanData($resumeInfo[$section]);
                }
                $resultList[$resumeId] = $resumeInfo;
            }
        }

        return $resultList;
    }

    /**
     * Notes:resumeId 获取简历工作信息
     * @param $resumeIds
     * @return array
     */
    public function getResumeWorkInfo($resumeIds){
        if (!$resumeIds){
            return [];
        }
        $columnNme = "id,resumeid,starttime,endtime,company,duty,salary,content,workindustry,workindustrytext";
        $orderByStr = "order by resumeid,IF(starttime='0000-00-00 00:00:00','9999-01-01',starttime) desc,
                                         IF(endtime='0000-00-00 00:00:00','9999-01-01',endtime) desc,id";
        $sql = 'select ' . $columnNme . ' from ResumeWork where resumeid in(' . mergeArrSql($resumeIds) . ') and status=? ' . $orderByStr;
        $var = array_merge($resumeIds, ['01']);
        $workList = Db::select($sql, $var);
        $resultList = [];
        foreach ($workList as $key => $item) {
            $item['isoverseas'] = 0;
            if ($item['workindustry'] != '') {
                $attributes = [
                    'workindustry' => [DictConstant::DD_INDUSTRY, ''],
                ];
                $this->dict->rowTrans($item, $attributes, true);
            }
            if ($item['workindustry'] == '') {
                $item['workindustry'] = $item['workindustrytext'];
                unset($item['workindustrytext']);
            }

            $item['score'] = '';
            $item['department'] = '';
            $item['rawduty'] = $item['duty'];
            $item['workdescribe'] = $item['content'];
            $item['leavereason'] = '';
            $item['companysize'] = '';
            $item['companytype'] = '';
            $item['reportboss'] = '';
            $item['reportperson'] = '';
            $item['workfunc'] = '';
            $item['worktype'] = '';
            $resultList[$item['resumeid']][] = $item;
        }
        return $resultList;
    }

    ///////////////////////////////////////////
    /// add by albafica 20190827
    ///////////////////////////////////////////


    /**
     * 下载简历
     * @param $oprId
     * @param array $resumeIds
     * @return array
     */
    public function downloadResume($oprId, array $resumeIds) {
        $userModel = new UserModel();
        $userInfo = $userModel->getInfo($oprId, 'userid, cname, downloadcount, teamcode, teamid');

        $alreadyDownResumeIds = $this->getDownloadResumeId($oprId, $resumeIds, true);
        $needDownResumeIds = array_diff($resumeIds, $alreadyDownResumeIds);
        if (empty($needDownResumeIds)) {
            return ['status' => 1, 'message' => '没有需要下载的简历'];
        }
        if (empty($userInfo) || $userInfo['downloadcount'] < count($needDownResumeIds)) {
            return ['status' => -1, 'message' => '下载数余额不足'];
        }

        $needCoinCount = count($needDownResumeIds);
        $memo = '下载简历[' . implode(',', $needDownResumeIds) . ']';
        $coinModel = new CoinModel();
        $downloadStatement = $coinModel->prepareCoinStatement(0, '', $oprId, CoinModel::TYPE_USER_USE, $needCoinCount, '', $memo);
        if ($downloadStatement['status'] != 0) {
            return $downloadStatement;
        }
        $downloadStatement = $downloadStatement['statements'];
        $resumeDownInsSql = 'INSERT INTO ResumeDownload(resumeid,oprid,oprteamcode,oprteamid,createdate,updatedate) VALUES ';
        $resumeDownInsVar = [];
        foreach ($needDownResumeIds as $needDownResumeId) {
            $resumeDownInsSql .= '(?,?,?,?,Now(),Now()),';
            $resumeDownInsVar = array_merge($resumeDownInsVar, [$needDownResumeId, $oprId, $userInfo['teamcode'], $userInfo['teamid']]);
        }
        $resumeDownInsSql = substr($resumeDownInsSql, 0, -1);
        $downloadStatement[] = Db::connect()->prepareStatement($resumeDownInsSql, $resumeDownInsVar);

        if (!Db::connect()->prepareTransactionStatement(true, ...$downloadStatement)->execute()) {
            return [
                'status' => -9,
                'message' => '系统繁忙，请稍后再试',
            ];
        }
        //ResumeDownload表新增记录，需要将resumeid同步到es引擎
        $resumeUpdate = new ResumeUpdate();
        $resumeUpdate->addToQueue($needDownResumeIds);
        return [
            'status' => 0,
            'message' => '下载成功',
            'needDownResumeIds' => $needDownResumeIds,
        ];

    }

    /**
     * 根据给定的简历id，获取其中已下载简历
     * @param $oprId
     * @param array $resumeIds
     * @param bool $includeTeam 是否包含同一大团队（及在同一个一级团队下）
     * @return array
     */
    public function getDownloadResumeId($oprId, array $resumeIds, bool $includeTeam = false) {
        $resumeIds = array_values(array_unique(array_filter($resumeIds)));
        if (empty($resumeIds) || count($resumeIds) == 0) {
            return [];
        }

        $includeTeam = false; //51job简历下载调整为不区分团队
        if ($includeTeam) {
            $oprModel = new UserModel();
            $oprInfo = $oprModel->getInfo($oprId, 'userid,teamcode,teamid');
            if (empty($oprInfo)) {
                throw new RuntimeException('登录账号出现异常');
            }

            $parentTeamCode = !empty($oprInfo['teamcode']) ? substr($oprInfo['teamcode'], 0, 5) : '';

            if (!empty($parentTeamCode)) {
                return $this->getDownloadResumeIdWithTeamCode($parentTeamCode, $resumeIds);
            }
        }

        $inFlag = substr(str_repeat('?,', count($resumeIds)), 0, -1);

        //51job简历下载调整为不区分团队
        //$sql = 'SELECT resumeid FROM ResumeDownload WHERE oprid=? AND resumeid IN(' . $inFlag . ') ';
        //$var = array_merge([$oprId], $resumeIds);

        $sql = 'SELECT resumeid FROM ResumeDownload WHERE resumeid IN(' . $inFlag . ') ';
        $var = $resumeIds;

        $result = Db::connect()->select($sql, $var);
        $downloadList = [];
        foreach ($result as $item) {
            $downloadList[] = intval($item['resumeid']);
        }
        $noDownResumeIds = array_diff($resumeIds, $downloadList);
        foreach ($noDownResumeIds as $key => $item) {
            if ($item < 2400000000) {
                unset($noDownResumeIds[$key]);
            }
        }
        if (empty($noDownResumeIds)) {
            return $downloadList;
        }
        //判断是否上传简历
        $inFlag = substr(str_repeat('?,', count($noDownResumeIds)), 0, -1);
        //$sql = 'SELECT resumeid FROM UploadResume WHERE oprid=? AND resumeid IN(' . $inFlag . ')';
        //$var = array_merge([$oprId], $noDownResumeIds);
        $sql = 'SELECT resumeid FROM UploadResume WHERE resumeid IN(' . $inFlag . ')';
        $var = $noDownResumeIds;

        $result = Db::connect()->select($sql, $var);
        foreach ($result as $item) {
            $downloadList[] = intval($item['resumeid']);
        }
        return $downloadList;
    }

    /**
     * 根据给定的简历id，获取其中同一团队成员有人下载过的简历
     * @param $teamCode
     * @param array $resumeIds
     * @return array
     */
    public function getDownloadResumeIdWithTeamCode($teamCode, array $resumeIds) {
        if (empty($teamCode)) {
            return [];
        }
        $inFlag = substr(str_repeat('?,', count($resumeIds)), 0, -1);
        $sql = 'SELECT distinct resumeid FROM ResumeDownload WHERE oprid IN(SELECT userid FROM User WHERE teamcode like ? AND status=?) AND resumeid IN(' . $inFlag . ')';
        $var = array_merge([$teamCode . '%', '01'], $resumeIds);
        $result = Db::connect()->select($sql, $var);
        $downloadList = [];
        foreach ($result as $item) {
            $downloadList[] = intval($item['resumeid']);
        }
        $noDownResumeIds = array_diff($resumeIds, $downloadList);
        foreach ($noDownResumeIds as $key => $item) {
            if ($item < 2400000000) {
                unset($noDownResumeIds[$key]);
            }
        }
        if (empty($noDownResumeIds)) {
            return $downloadList;
        }
        //判断是否上传简历
        $inFlag = substr(str_repeat('?,', count($noDownResumeIds)), 0, -1);
        //$sql = 'SELECT resumeid FROM UploadResume WHERE oprid IN(SELECT userid FROM User WHERE teamcode like ? AND status=?) AND resumeid IN(' . $inFlag . ')';
        //$var = array_merge([$teamCode . '%', '01'], $noDownResumeIds);
        $sql = 'SELECT resumeid FROM UploadResume WHERE resumeid IN(' . $inFlag . ')';
        $var = $noDownResumeIds;
        $result = Db::connect()->select($sql, $var);
        foreach ($result as $item) {
            $downloadList[] = intval($item['resumeid']);
        }
        return $downloadList;
    }

    /**
     * 添加简历附件
     * @param $file
     * @param $oprId
     * @param $resumeId
     * @param $fileType 01-简历附件 02-其他附件
     * @param null $attachName
     * @param bool $keepOld
     * @return array
     * @throws Exception
     */
    public function addAttach($file, $oprId, $resumeId, $fileType, $attachName = null, $keepOld = false) {
        $validateRule = [
            'attach' => [
                'required', 'file', 'minSize' => 0, 'maxSize' => 10240
            ],
            'resumeid' => ['required', 'int', 'min' => 1]
        ];

        $message = [
            'attach' => '请上传不超过10M大小的简历附件',
            'resumeid' => '请选择简历'
        ];
        if ($fileType == '01') {
            //$validateRule['attach']['mimes'] = ['doc', 'docx', 'pdf', 'txt'];
            //$message['attach.mimes'] = '请上传doc、docx、pdf、txt格式的简历附件';
        } else {
            $fileType = '02';
        }

        $validate = new Validator($validateRule, $message);
        if (!$validate->validate(['attach' => $file, 'resumeid' => $resumeId])) {
            return [
                'status' => false,
                'message' => '校验失败',
                'validateFailure' => $validate->getErrors()
            ];
        }
        $attachModel = new AttachModel();
        if ($file instanceof UploadedFile) {
            $uploadInfo = $attachModel->uploadAttach($file, AttachModel::MODULE_RESUME, $oprId, $attachName);
        } else {
            $uploadInfo = $attachModel->moveAttach($file, AttachModel::MODULE_RESUME, $oprId, $attachName, $keepOld);
        }

        if (!$uploadInfo) {
            return [
                'status' => false,
                'message' => '上传文件失败',
                'fileinfo' => ''
            ];
        }

        $insAttachSql = 'INSERT INTO ResumeAttach(resumeid, attachid, attachtype, creator, createdate, updator, updatedate, status) VALUES (?,?,?,?,Now(),?,Now(),?)';
        $insAttachVar = [$resumeId, $uploadInfo['fileid'], $fileType, $oprId, $oprId, '01'];

        Db::connect()->insert($insAttachSql, $insAttachVar);
        return [
            'status' => true,
            'message' => '上传成功',
            'fileinfo' => $uploadInfo
        ];
    }

    //查询简历附件
    public function showAttach($resumeId) {
        $sql = 'select id as resumeattachid,u.cname as username,u.userid,ra.createdate,ra.attachtype,attachid from ResumeAttach as ra
                left join User as u on ra.creator = u.userid
                where ra.resumeid = ? and ra.status = ? order by id desc';
        return Db::select($sql, [$resumeId, '01']);
    }

    //获得简历附件名以及路径
    public function getAttachPath($resumeAttachId) {
        $sql = 'select a.attachname,a.filepath,ra.id,ra.creator from ResumeAttach as ra
                left join Attach as a on ra.attachid = a.attachid
                where ra.id = ? and ra.status = ? limit ?';
        return Db::selectOne($sql, [$resumeAttachId, '01', 1]);
    }

    //删除简历附件
    public function softDelResumeAttach($resumeAttachId) {
        $sql = 'update ResumeAttach set status = ? where id = ? and creator = ?';
        return Db::update($sql, ['06', $resumeAttachId, UserAuth::getLoginId()]);
    }

    protected function formatTimespanData(&$data, $asArray = true, $language = 'cn') {
        if (!is_array($data)) return $data;
        foreach ($data as &$item) {
            if (isset($item['starttime']))
                $item['time'] = $this->renderTime($item['starttime'], $item['endtime'], $asArray, $language);
            elseif (isset($item['timefrom']))
                $item['time'] = $this->renderTime($item['timefrom'], $item['timeto'], $asArray, $language);
            elseif (isset($item['getdate']))
                $item['time'] = $this->renderTime($item['getdate'], true, $asArray, $language);
            elseif (isset($item['bonustime']))
                $item['time'] = $this->renderTime($item['bonustime'], true, $asArray, $language);
            else {
                return $data;
            }
        }
        usort($data, function ($a, $b) {    //正序a-b，倒序b-a
            $deltaFrom = $b['time']['fromts'] - $a['time']['fromts'];
            if ($deltaFrom != 0) return $deltaFrom;
            return $b['time']['tots'] - $a['time']['tots'];
        });
        return $data;
    }

    public function renderTime($from, $to = true, $returnArray = false, $language = 'cn') {
        if ($this->isEmptyDate($from)) return $returnArray ? ['fromts' => 0, 'from' => '', 'tots' => 0, 'to' => '', 'full' => '', 'timespan' => ''] : '';
        if (!is_numeric($from)) $from = strtotime($from);
        $result = ['fromts' => $from, 'from' => date('Y/m', $from), 'timespan' => ''];
        if (!empty($to)) {
            if (is_string($to)) {
                $result['tots'] = strtotime($to);
            }
            if (!empty($result['tots']) && is_numeric($result['tots'])) {
                $result['to'] = date('Y/m', $result['tots']);
            } else {
                $result['tots'] = $result['fromts'];
                $result['to'] = $result['from'];
            }
        } else {
            $result['tots'] = PHP_INT_MAX;
            $result['to'] = $language == 'en' ? 'Present' : '至今';
        }
        $result['full'] = empty($result['to']) || $result['to'] == $result['from'] ? $result['from'] : $result['from'] . ' - ' . $result['to'];

        if ($result['tots'] - $result['fromts'] >= 86400 * 28) {
            $tots = $result['tots'] > time() ? time() : $result['tots'];
            $timespan = strtotime('0001-01-00') + $tots - $result['fromts'];
            $year = intval(date('Y', $timespan)) - 1;
            $month = intval(date('m', $timespan));
            $day = intval(date('d', $timespan));
            if ($day < 28 && ($year > 0 || $month > 1)) $month--;
            if ($month == 12) {
                $year++;
                $month = 0;
            }
            if ($language == 'en') {
                if ($year > 0) $result['timespan'] .= $year . ($year > 1 ? ' years' : ' year');
                if ($year > 0 && $month > 0) $result['timespan'] .= ' and ';
                if ($month > 0) $result['timespan'] .= $month . ($month > 1 ? ' months' : ' month');
            } else {
                if ($year > 0) $result['timespan'] .= $year . '年';
                if ($month > 0) $result['timespan'] .= $month . '个月';
            }
        } else {
            if ($language == 'en') {
                $result['timespan'] = 'less than one month';
            } else {
                $result['timespan'] = '一个月内';
            }
        }
        return $returnArray ? $result : $result['full'];
    }

    public function renderSalary($unit, $from, $to = null) {
        if (empty($from)) return '';
        $text = $from;
        if (!empty($to) && $to > $from) $text .= ' - ' . $to;
        if (!empty($unit)) $text .= ' ' . $unit;
        return $text;
    }

    public function isEmptyDate($date) {
        if (empty($date)) return true;
        if ($date == '0000-00-00 00:00:00') return true;    //0000-00-00
        $timestamp = @strtotime($date);
        if (empty($timestamp) || abs($timestamp) < 86400) return true;   //1970-01-01
        if (date('Y-m-d', $timestamp) == '-0001-11-30') return true;    //0000-00-00
        return false;
    }

    /**
     * 返回当前已读简历redis的key值。
     * @param $isread  true 对，否则为写
     * @return array
     */
    public function getReadResumeKey($isRead = true) {
        $key = [];
        $nowYear = date('Y');
        $nowMonth = date('m');

        //本季度
        switch ($nowMonth) {
            case "01":
            case "02":
            case "03":
                $key['now'] = $nowYear . '_1';
                break;
            case "04":
            case "05":
            case "06":
                $key['now'] = $nowYear . '_2';
                break;
            case "07":
            case "08":
            case "09":
                $key['now'] = $nowYear . '_3';
                break;
            default:
                $key['now'] = $nowYear . '_4';
                break;
        }

        //上一季度
        if ($isRead) {
            switch ($nowMonth) {
                case "01":
                case "02":
                case "03":
                    $key['prev'] = ($nowYear - 1) . '_4';
                    break;
                case "04":
                case "05":
                case "06":
                    $key['prev'] = $nowYear . '_1';
                    break;
                case "07":
                case "08":
                case "09":
                    $key['prev'] = $nowYear . '_2';
                    break;
                default:
                    $key['prev'] = $nowYear . '_3';
                    break;
            }
        }

        return $key;
    }

    /**
     * 编辑简历基本信息
     * @param $oprId  编辑人ID
     * @param $resumeId  简历ID
     * @param $resumeInfo  编辑字段详情
     * @return array
     */
    public function saveNewResume($oprId, $resumeInfo) {
        $ruleConf = [
            'cname' => [
                'cname|姓名' => [
                    'minLength' => '1', 'maxLength' => '10'
                ]],
            'gender' => [
                'gender|性别' => [
                    'maxLength' => '1'
                ]],
            'phone' => [
                'phone|手机' => [
                    'minLength' => '7', 'maxLength' => '19'
                ]],
            'email' => [
                'email|邮箱' => [
                    'maxLength' => '30', 'email'
                ]],
            'birthday' => [
                'birthday|生日' => [
                    'dateFormat' => 'Y-m-d'
                ]],
            'workyear' => [
                'workyear|开始工作年份' => [
                    'minLength' => '4', 'maxLength' => '4'
                ]],
            'area' => [
                'area|所在城市' => [
                    'minLength' => '6', 'maxLength' => '6'
                ]],
            'situation' => [
                'situation|求职状态' => [
                    'minLength' => '1', 'maxLength' => '1'
                ]]
        ];

        if (isset($resumeInfo['phone'])) {
            if (preg_match('/(^(((\+)?\d{1,4}-)\d{5,15}$)|(^1\d{10}$))/', $resumeInfo['phone']) == 0) {
                return ['status' => false, 'message' => '校验失败', 'errorFields' => ['phone' => '手机格式不正确']];
            }

            $resumeInfo['phone'] = ltrim($resumeInfo['phone'], '+');
            $phoneArr = explode("-", $resumeInfo['phone']);
            if (count($phoneArr) == 2) {
                if ($phoneArr[0] == 86) {
                    $resumeInfo['phone'] = $phoneArr[1];
                } else {
                    $resumeInfo['phone'] = ltrim($resumeInfo['phone'], 0);
                }
            }
        }

        $rule = [];
        foreach ($resumeInfo as $key => $item) {
            if (isset($ruleConf[$key])) {
                $rule = array_merge($rule, $ruleConf[$key]);
            }
        }

        if (empty($rule)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '没有任何修改信息'];
        }

        $validate = new Validator($rule);
        $result = $validate->validate($resumeInfo);
        if (!$result) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => $validate->getErrors()];
        }

        $sqlStr = "select seq_manager_userid.nextval as resumeid,seq_account_accountid.nextval as accountid,seq_manager_managerid.nextval as managerid from dual";
        $seqInfo = Db::connect('jyrpo_oracle')->selectOne($sqlStr);
        if (empty($seqInfo) || !isset($seqInfo['resumeid'])) {
            return ['status' => false, 'message' => '获取简历ID失败'];
        }

        $resumeId = $seqInfo['resumeid'];

        $rollbackIfNoAffect = true;

        //s_account
        $sql = 'INSERT INTO s_account (accountid, mastermgrid, createdate, lastupdate, activedate, isactive, dbid, isjyacc) values (?,         ?,           sysdate,    sysdate,    sysdate,    ?,        ?,    ?)';
        $var = [$seqInfo['accountid'], $seqInfo['managerid'], 1, 1, 1];
        $tmpStatement = Db::connect('jyrpo_oracle')->prepareStatement($sql, $var);
        $transStatements[] = Db::connect('jyrpo_oracle')->prepareTransactionStatement($rollbackIfNoAffect, $tmpStatement);

        //s_manager
        $sql = "INSERT INTO s_manager (ManagerID,UserID51job,AccountID51job,relationaccid,CName,Email,MobilePhone,Area,Gender,WorkYear,Birthday,
                                       agenttype,isactive,isprofile,openstatus,ownerspyid,source,isjycv,ResumeDate,activedate, createdate,lastupdate)
                                values (?,       ?,             ?,          ?,            ?,     ?,   ?,          ?,    ?,    ?,TO_DATE(?, 'YYYY-MM-DD'),
                                       '2',      '1',      '0',     '2',       0,         8,     1,     sysdate,    sysdate,    sysdate,  sysdate)";
        $var = [$seqInfo['managerid'], $resumeId, $seqInfo['accountid'], $seqInfo['accountid'],
            mb_substr($resumeInfo['cname'], 0, 9),
            mb_substr($resumeInfo['email'], 0, 49),
            mb_strcut($resumeInfo['phone'], 0, 20),
            substr($resumeInfo['area'], 0, 6),
            $resumeInfo['gender'],
            $resumeInfo['workyear'],
            $resumeInfo['birthday']
        ];

        $tmpStatement = Db::connect('jyrpo_oracle')->prepareStatement($sql, $var);
        $transStatements[] = Db::connect('jyrpo_oracle')->prepareTransactionStatement($rollbackIfNoAffect, $tmpStatement);

        $sql = 'INSERT INTO RpoResumeEditHis (oprid,oprtype,resumeid,createdate,updatedate)
                                      values (?,    ?,      ?,       Now(),    Now())';
        $var = [$oprId, '03', $resumeId];
        $tmpStatement = Db::connect('jyrpo')->prepareStatement($sql, $var);
        $transStatements[] = Db::connect('jyrpo')->prepareTransactionStatement($rollbackIfNoAffect, $tmpStatement);

        //用户手动新增简历关系
        $sql = "INSERT INTO UploadResume (resumeid,taskid,oprid,status,type,source,createdate,updatedate)
                                  values (?,       ?,     ?,    ?,     ?,   ?,     Now(),     Now())";
        $var = [$resumeId, 0, $oprId, '01', '01', 13];
        $tmpStatement = Db::connect('jyrpo')->prepareStatement($sql, $var);
        $transStatements[] = Db::connect('jyrpo')->prepareTransactionStatement($rollbackIfNoAffect, $tmpStatement);

        $fileToResumeObject = new FileToResume();
        $trimName = $fileToResumeObject->formatName($resumeInfo['cname']);

        //简历表
        $sql = "INSERT INTO RpoResume (resumeid,gender,phone,email,cname,trimcname,workyear,area,situation,birthday,
                                       creator,updator,createdate,updatedate,status,source,hasworkinfo,hasprojectinfo,haseducationinfo)
                               values (?,       ?,     ?,    ?,     ?,    ?,       ?,       ?,   ?,        STR_TO_DATE(?,'%Y-%m-%d'),
                                       ?,       ?,     Now(),     Now(),     '01',  13,    0,           0,            0)";
        $var = [$resumeId,
            $resumeInfo['gender'],
            mb_substr($resumeInfo['phone'], 0, 20),
            mb_substr($resumeInfo['email'], 0, 100),
            mb_substr($resumeInfo['cname'], 0, 50),
            mb_substr($trimName, 0, 50),
            $resumeInfo['workyear'],
            mb_substr($resumeInfo['area'], 0, 6),
            $resumeInfo['situation'],
            $resumeInfo['birthday'],
            $oprId,
            $oprId];
        $tmpStatement = Db::connect('jyrpo')->prepareStatement($sql, $var);
        $transStatements[] = Db::connect('jyrpo')->prepareTransactionStatement($rollbackIfNoAffect, $tmpStatement);

        //使用跨库执行方法 multiTransaction 生成跨库句柄并调用execute方法
        $result = Db::multiTransaction(...$transStatements)->execute();
        if (!$result) {
            return ['status' => false, 'message' => '保存失败'];
        }
        //CaseResume表新增记录，需要将resumeid同步到es引擎
        $resumeUpdate = new ResumeUpdate();
        $resumeUpdate->addToQueue($resumeId);
        return ['status' => true, 'message' => '保存成功', 'resumeid' => $resumeId];
    }


    /**
     * 编辑简历基本信息
     * @param $oprId  编辑人ID
     * @param $resumeId  简历ID
     * @param $resumeInfo  编辑字段详情
     * @return array
     */
    public function saveEditResume($oprId, $resumeId, $resumeInfo) {
        $ruleConf = [
            'cname' => [
                'cname|姓名' => [
                    'minLength' => '1', 'maxLength' => '10'
                ]],
            'gender' => [
                'gender|性别' => [
                    'maxLength' => '1'
                ]],
            'phone' => [
                'phone|手机' => [
                    'minLength' => '7', 'maxLength' => '19'
                ]],
            'email' => [
                'email|邮箱' => [
                    'maxLength' => '30', 'email'
                ]],
            'birthday' => [
                'birthday|生日' => [
                    'dateFormat' => 'Y-m-d'
                ]],
            'workyear' => [
                'workyear|开始工作年份' => [
                    'minLength' => '4', 'maxLength' => '4'
                ]],
            'area' => [
                'area|所在城市' => [
                    'minLength' => '6', 'maxLength' => '6'
                ]],
            'expectarea' => [
                'expectarea|期望工作城市' => [
                    'maxLength' => '50'
                ]],
            'salaryfrom' => [
                'salaryfrom|目前薪资开始' => [
                    'int', 'min' => 0
                ]],
            'salaryto' => [
                'salaryto|目前薪资结束' => [
                    'int', 'min' => 0
                ]],
            'expectsalaryfrom' => [
                'expectsalaryfrom|期望薪资开始' => [
                    'int', 'min' => 0
                ]],
            'expectsalaryto' => [
                'expectsalaryto|期望薪资结束' => [
                    'int', 'min' => 0
                ]],
            'workindustry' => [
                'workindustry|行业' => [
                    'minLength' => '2', 'maxLength' => '2'
                ]],
            'position' => [
                'position|职能' => [
                    'maxLength' => '49'
                ]],
            'selfintro' => [
                'selfintro|自我评价' => [
                    'maxLength' => '10000'
                ]],
            'jobterm' => [
                'jobterm|工作类型' => [
                    'minLength' => '1', 'maxLength' => '1'
                ]],
            'situation' => [
                'situation|求职状态' => [
                    'minLength' => '1', 'maxLength' => '1'
                ]],
            'entrytime' => [
                'entrytime|到岗时间' => [
                    'minLength' => '1', 'maxLength' => '1'
                ]],
            'nofocuse' => [
                'nofocuse|勿推企业' => [
                    'maxLength' => '1000'
                ]],
            'skillinfo' => [
                'skillinfo|技能特长' => [
                    'maxLength' => '1000'
                ]],
            'awardinfo' => [
                'awardinfo|奖项荣誉' => [
                    'maxLength' => '1000'
                ]],
            'otherinfo' => [
                'otherinfo|其他信息' => [
                    'maxLength' => '1000'
                ]]
        ];

        if (isset($resumeInfo['phone'])) {
            if (preg_match('/(^(((\+)?\d{1,4}-)\d{5,15}$)|(^1\d{10}$))/', $resumeInfo['phone']) == 0) {
                return ['status' => false, 'message' => '校验失败', 'errorFields' => ['phone' => '手机格式不正确']];
            }

            $resumeInfo['phone'] = ltrim($resumeInfo['phone'], '+');
            $phoneArr = explode("-", $resumeInfo['phone']);
            if (count($phoneArr) == 2) {
                if ($phoneArr[0] == 86) {
                    $resumeInfo['phone'] = $phoneArr[1];
                } else {
                    $resumeInfo['phone'] = ltrim($resumeInfo['phone'], 0);
                }
            }
        }

        $var = $var_oracle = $rule = [];
        $updateFields = $updateFields_oracle = '';
        $fieldNameRelation = ['cname' => 'cname', 'gender' => 'gender', 'phone' => 'mobilephone', 'email' => 'email', 'birthday' => 'birthday',
            'workyear' => 'workyear', 'area' => 'area', 'expectarea' => 'expectarea', 'salaryfrom' => 'currsalaryfrom', 'salaryto' => 'currsalaryto',
            'expectsalaryfrom' => 'expsalaryfrom', 'expectsalaryto' => 'expsalaryto', 'workindustry' => 'workindustry', 'position' => 'position',
            'selfintro' => '', 'jobterm' => '', 'situation' => '', 'entrytime' => '',
            'nofocuse' => '', 'skillinfo' => '', 'awardinfo' => '', 'otherinfo' => ''];
        foreach ($resumeInfo as $key => $item) {
            if (isset($ruleConf[$key])) {
                $rule = array_merge($rule, $ruleConf[$key]);
                $var[] = $item;
                $updateFields .= " " . $key . "=?,";
                if ($key == 'cname') {
                    $fileToResumeObject = new FileToResume();
                    $trimName = $fileToResumeObject->formatName($item);
                    $var[] = $trimName;
                    $updateFields .= " " . $key . "=?,";
                }

                if (isset($fieldNameRelation[$key]) && $fieldNameRelation[$key] != '') {
                    $var_oracle[] = $item;
                    if ($key == 'birthday') {
                        $updateFields_oracle .= " " . $fieldNameRelation[$key] . "=TO_DATE(?,'YYYY-MM-DD'),";
                    } else {
                        $updateFields_oracle .= " " . $fieldNameRelation[$key] . "=?,";
                    }
                }
            }
        }

        if (empty($updateFields)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '没有任何修改信息'];
        }

        if (!empty($rule)) {
            $validate = new Validator($rule);
            $result = $validate->validate($resumeInfo);
            if (!$result) {
                return ['status' => false, 'message' => '校验失败', 'errorFields' => $validate->getErrors()];
            }
        }

        //检测简历是否是RPO简历
        $result = $this->getResumeBaseInfo($resumeId);
        if (empty($result)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '该简历ID不存在'];
        }

        $rollbackIfNoAffect = true;

        $sql = 'UPDATE RpoResume SET ' . trim($updateFields, ',') . ',updator=?,updatedate=now() WHERE resumeid=?';
        $var[] = $oprId;
        $var[] = $resumeId;
        $tmpStatement = Db::connect('jyrpo')->prepareStatement($sql, $var);
        $transStatements[] = Db::connect('jyrpo')->prepareTransactionStatement($rollbackIfNoAffect, $tmpStatement);

        //s_manager
        if (!empty($updateFields_oracle)) {
            $updateFields_oracle = trim($updateFields_oracle, ',') . ',';
        }
        $sql = "UPDATE s_manager set " . $updateFields_oracle . " lastupdate=sysdate where UserID51job=? ";
        $var_oracle[] = $resumeId;

        $tmpStatement = Db::connect('jyrpo_oracle')->prepareStatement($sql, $var_oracle);
        $transStatements[] = Db::connect('jyrpo_oracle')->prepareTransactionStatement($rollbackIfNoAffect, $tmpStatement);
        //使用跨库执行方法 multiTransaction 生成跨库句柄并调用execute方法
        $result = Db::multiTransaction(...$transStatements)->execute();
        if (!$result) {
            return ['status' => false, 'message' => '保存失败'];
        }

        if (isset($resumeInfo['selfintro'])) {
            $this->updateManagerProfile($resumeId);
        }

        $editType = '11';
        if (isset($resumeInfo['expectarea'])) {
            $editType = '12';
        } else if (isset($resumeInfo['nofocuse']) || isset($resumeInfo['skillinfo']) || isset($resumeInfo['awardinfo']) || isset($resumeInfo['otherinfo'])) {
            $editType = '16';
        }
        $this->addResumeEditLog($oprId, $resumeId, $editType);

        return ['status' => true, 'message' => '保存成功'];
    }


    /**
     * Notes:获取简历基本信息
     */
    public function getResumeBaseInfo($resumeId, $field = 'resumeid') {
        $sql = 'SELECT ' . $field . ' FROM RpoResume WHERE resumeid=?';
        $var = [$resumeId];
        return Db::selectOne($sql, $var);
    }

    /**
     * Notes:删除简历工作经历信息
     */
    public function delResumeWork($oprId, $resumeId, $id) {
        $sql = 'update ResumeWork set status = ?,updator = ?,updatedate = NOW() where id = ? and resumeid = ? and status != ?';
        $var = ['06', $oprId, $id, $resumeId, '06'];
        $result = Db::update($sql, $var);
        if ($result == 1) {
            $this->updateManagerProfile($resumeId);
            $editType = '13';
            $this->addResumeEditLog($oprId, $resumeId, $editType);
        }
        return $result;
    }

    /**
     * Notes:删除简历工作经历信息
     */
    public function delResumeProject($oprId, $resumeId, $id) {
        $sql = 'update ResumeProject set status = ?,updator = ?,updatedate = NOW() where id = ? and resumeid = ? and status != ?';
        $var = ['06', $oprId, $id, $resumeId, '06'];
        $result = Db::update($sql, $var);
        if ($result == 1) {
            $this->updateManagerProfile($resumeId);
            $editType = '14';
            $this->addResumeEditLog($oprId, $resumeId, $editType);
        }
        return $result;
    }

    /**
     * Notes:删除简历工作经历信息
     */
    public function delResumeEdu($oprId, $resumeId, $id) {
        $sql = 'update ResumeEdu set status = ?,updator = ?,updatedate = NOW() where id = ? and resumeid = ? and status != ?';
        $var = ['06', $oprId, $id, $resumeId, '06'];
        $result = Db::update($sql, $var);
        if ($result == 1) {
            $this->updateManagerProfile($resumeId);
            $editType = '15';
            $this->addResumeEditLog($oprId, $resumeId, $editType);
        }
        return $result;
    }

    /**
     * Notes:修改简历工作经历信息
     */
    public function saveResumeWork($oprId, $resumeId, $id, $itemInfo) {
        $ruleConf = [
            'starttime' => [
                'starttime|开始时间' => [
                    'required', 'dateFormat' => 'Y-m-d'
                ]],
            'endtime' => [
                'endtime|结束时间' => [
                    'dateFormat' => 'Y-m-d'
                ]],
            'company' => [
                'company|公司名称' => [
                    'required', 'maxLength' => '200'
                ]],
            'duty' => [
                'duty|职位' => [
                    'maxLength' => '100'
                ]],
            'salary' => [
                'salary|薪资' => [
                    'maxLength' => '100'
                ]],
            'content' => [
                'content|工作描述' => [
                    'maxLength' => '5000'
                ]],
            'workindustry' => [
                'workindustry|行业' => [
                    'minLength' => '2', 'maxLength' => '2'
                ]]
        ];
        $var = $rule = [];
        $updateFields = '';
        foreach ($itemInfo as $key => $item) {
            if (isset($ruleConf[$key])) {
                if ($key == 'endtime' && empty($item)) {
                    $updateFields .= " " . $key . "=null,";
                    //$var[] = '0000-00-00 00:00:00';
                } else {
                    $rule = array_merge($rule, $ruleConf[$key]);
                    $updateFields .= " " . $key . "=?,";
                    $var[] = $item;
                }
            }
        }

        if (empty($updateFields)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '没有任何修改信息'];
        }

        if (!empty($rule)) {
            $validate = new Validator($rule);
            $result = $validate->validate($itemInfo);
            if (!$result) {
                return ['status' => false, 'message' => '校验失败', 'errorFields' => $validate->getErrors()];
            }
        }

        if (isset($itemInfo['workindustry']) && !empty($itemInfo['workindustry'])) {
            $updateFields .= " workindustrytext=?,";
            $var[] = '';
        }

        //检测简历是否是RPO简历
        $result = $this->getResumeBaseInfo($resumeId);
        if (empty($result)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '该简历ID不存在'];
        }

        if (empty($id)) {
            $insSql = 'INSERT INTO ResumeWork(resumeid,company,status,creator,createdate) values (?,?,?,?,now())';
            $insVar = [$resumeId, $itemInfo['company'], '01', $oprId];
            Db::connect('jyrpo_pdo')->insert($insSql, $insVar);
            $id = Db::connect('jyrpo_pdo')->getLastInsertId();
        }
        if (empty($id) || $id < 0) {
            return ['status' => false, 'message' => '保存失败,请稍后再试'];
        }

        $sql = 'update ResumeWork set ' . trim($updateFields, ',') . ',updator = ?,updatedate = NOW() where id = ? and resumeid = ?';
        $var[] = $oprId;
        $var[] = $id;
        $var[] = $resumeId;
        $result = Db::update($sql, $var);
        if ($result == 1) {
            $this->updateManagerProfile($resumeId);
            $editType = '13';
            $this->addResumeEditLog($oprId, $resumeId, $editType);
        }
        return [
            'status' => $result == 1,
            'message' => $result == 1 ? '保存成功' : '保存失败,请稍后再试'
        ];
    }

    /**
     * Notes:修改简历项目经验信息
     */
    public function saveResumeProject($oprId, $resumeId, $id, $itemInfo) {
        $ruleConf = [
            'starttime' => [
                'starttime|开始时间' => [
                    'required', 'dateFormat' => 'Y-m-d'
                ]],
            'endtime' => [
                'endtime|结束时间' => [
                    'dateFormat' => 'Y-m-d'
                ]],
            'company' => [
                'company|公司名称' => [
                    'required', 'maxLength' => '200'
                ]],
            'duty' => [
                'duty|职位' => [
                    'maxLength' => '100'
                ]],
            'project' => [
                'project|项目名称' => [
                    'maxLength' => '200'
                ]],
            'content' => [
                'content|项目描述' => [
                    'maxLength' => '5000'
                ]]
        ];
        $var = $rule = [];
        $updateFields = '';
        foreach ($itemInfo as $key => $item) {
            if (isset($ruleConf[$key])) {
                if ($key == 'endtime' && empty($item)) {
                    $updateFields .= " " . $key . "=null,";
                    //$var[] = '0000-00-00 00:00:00';
                } else {
                    $rule = array_merge($rule, $ruleConf[$key]);
                    $updateFields .= " " . $key . "=?,";
                    $var[] = $item;
                }
            }
        }

        if (empty($updateFields)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '没有任何修改信息'];
        }

        if (!empty($rule)) {
            $validate = new Validator($rule);
            $result = $validate->validate($itemInfo);
            if (!$result) {
                return ['status' => false, 'message' => '校验失败', 'errorFields' => $validate->getErrors()];
            }
        }

        //检测简历是否是RPO简历
        $result = $this->getResumeBaseInfo($resumeId);
        if (empty($result)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '该简历ID不存在'];
        }

        if (empty($id)) {
            $insSql = 'INSERT INTO ResumeProject(resumeid,project,status,creator,createdate) values (?,?,?,?,now())';
            $insVar = [$resumeId, $itemInfo['project'], '01', $oprId];
            Db::connect('jyrpo_pdo')->insert($insSql, $insVar);
            $id = Db::connect('jyrpo_pdo')->getLastInsertId();
        }
        if (empty($id) || $id < 0) {
            return ['status' => false, 'message' => '保存失败,请稍后再试'];
        }

        $sql = 'update ResumeProject set ' . trim($updateFields, ',') . ',updator = ?,updatedate = NOW() where id = ? and resumeid = ?';
        $var[] = $oprId;
        $var[] = $id;
        $var[] = $resumeId;
        $result = Db::update($sql, $var);
        if ($result == 1) {
            $this->updateManagerProfile($resumeId);
            $editType = '14';
            $this->addResumeEditLog($oprId, $resumeId, $editType);
        }
        return [
            'status' => $result == 1,
            'message' => $result == 1 ? '保存成功' : '保存失败,请稍后再试'
        ];
    }


    /**
     * Notes:修改简历项目经验信息
     */
    public function saveResumeEdu($oprId, $resumeId, $id, $itemInfo) {
        $ruleConf = [
            'starttime' => [
                'starttime|开始时间' => [
                    'required', 'dateFormat' => 'Y-m-d'
                ]],
            'endtime' => [
                'endtime|结束时间' => [
                    'dateFormat' => 'Y-m-d'
                ]],
            'school' => [
                'school|学校名称' => [
                    'required', 'maxLength' => '100'
                ]],
            'major' => [
                'major|专业' => [
                    'maxLength' => '4'
                ]],
            'degree' => [
                'degree|学历' => [
                    'maxLength' => '1'
                ]],
            'content' => [
                'content|备注' => [
                    'maxLength' => '5000'
                ]]
        ];

        $var = $rule = [];
        $updateFields = '';
        foreach ($itemInfo as $key => $item) {
            if (isset($ruleConf[$key])) {
                if ($key == 'endtime' && empty($item)) {
                    $updateFields .= " " . $key . "=null,";
                    //$var[] = '0000-00-00 00:00:00';
                } else {
                    $rule = array_merge($rule, $ruleConf[$key]);
                    if ($key == 'major' || $key == 'degree') {
                        if (empty($item)) {
                            //continue;
                        }
                        $updateFields .= " " . $key . "=?,";
                        $var[] = '';
                        $key .= '_code';
                    }
                    $updateFields .= " " . $key . "=?,";
                    $var[] = $item;
                }
            }
        }

        if (empty($updateFields)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '没有任何修改信息'];
        }

        if (!empty($rule)) {
            $validate = new Validator($rule);
            $result = $validate->validate($itemInfo);
            if (!$result) {
                return ['status' => false, 'message' => '校验失败', 'errorFields' => $validate->getErrors()];
            }
        }

        //检测简历是否是RPO简历
        $result = $this->getResumeBaseInfo($resumeId);
        if (empty($result)) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => '该简历ID不存在'];
        }

        if (empty($id)) {
            $insSql = 'INSERT INTO ResumeEdu(resumeid,school,status,creator,createdate) values (?,?,?,?,now())';
            $insVar = [$resumeId, $itemInfo['school'], '01', $oprId];
            Db::connect('jyrpo_pdo')->insert($insSql, $insVar);
            $id = Db::connect('jyrpo_pdo')->getLastInsertId();
        }
        if (empty($id) || $id < 0) {
            return ['status' => false, 'message' => '保存失败,请稍后再试'];
        }

        $sql = 'update ResumeEdu set ' . trim($updateFields, ',') . ',updator = ?,updatedate = NOW() where id = ? and resumeid = ?';
        $var[] = $oprId;
        $var[] = $id;
        $var[] = $resumeId;
        $result = Db::update($sql, $var);
        if ($result == 1) {
            $this->updateManagerProfile($resumeId);
            $editType = '15';
            $this->addResumeEditLog($oprId, $resumeId, $editType);
        }
        return [
            'status' => $result == 1,
            'message' => $result == 1 ? '保存成功' : '保存失败,请稍后再试'
        ];
    }

    /**
     * Notes:修改精英网s_manager表的profile字段和RpoResume的是否有工作经历、项目经历、教育经历
     */
    public function updateManagerProfile($resumeId) {
        $resumeIds = array($resumeId);
        $resumeModel = new ResumeModel();
        $resumeModel->arrValueToKey($resumeIds);
        $resumeInfoArr = $resumeModel->getResumeInfo($resumeIds, true);
        $resumeInfo = $resumeInfoArr[array_key_first($resumeIds)];
        $profile = '';
        if (!empty($resumeInfo['selfintro']) && is_string($resumeInfo['selfintro'])) {
            $profile .= PHP_EOL . PHP_EOL . '【自我评价】' . PHP_EOL . $resumeInfo['selfintro'];
        }

        static $delimiter = ' | ';
        $hasworkinfo = $hasprojectinfo = $haseducationinfo = '0';
        $company = '';
        if (is_array($resumeInfo['workinfo']) && count($resumeInfo['workinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【工作经历】';
            $hasworkinfo = '1';
            foreach ($resumeInfo['workinfo'] as $item) {
                if ($company == '') {
                    $company = substr($item['company'], 0, 100);
                }

                $profile .= PHP_EOL . implode($delimiter, array_filter([$item['time']['full'], $item['company'], $item['duty'], $item['salary'], $item['workindustry']])) . PHP_EOL . $item['content'];
            }
        }

        if (is_array($resumeInfo['projectinfo']) && count($resumeInfo['projectinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【项目经历】';
            $hasprojectinfo = '1';
            foreach ($resumeInfo['projectinfo'] as $item) {
                $profile .= PHP_EOL . implode($delimiter, array_filter([$item['time']['full'], $item['project'], $item['company'], $item['duty']])) . PHP_EOL . $item['content'];
            }
        }

        $schoolJY = $school = $major_code = $degree_code = '';
        if (is_array($resumeInfo['educationinfo']) && count($resumeInfo['educationinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【教育经历】';
            $haseducationinfo = '1';
            foreach ($resumeInfo['educationinfo'] as $item) {
                if ($school == '') {
                    $school = substr($item['school'], 0, 100);
                    $major_code = $item['major_code'];
                    $degree_code = $item['degree_code'];
                }
                $profile .= PHP_EOL . implode($delimiter, array_filter([$item['time']['full'], $item['school'], $item['major'], $item['degree']]));
                if (!empty($item['comment'])) $profile .= PHP_EOL . $item['content'];
            }
        }

        if (!empty($resumeInfo['skillinfo']) && is_string($resumeInfo['skillinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【技能特长】' . PHP_EOL . $resumeInfo['skillinfo'];
        }

        if (!empty($resumeInfo['awardinfo']) && is_string($resumeInfo['awardinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【获奖情况】' . PHP_EOL . $resumeInfo['awardinfo'];
        }

        if (!empty($resumeInfo['otherinfo']) && is_string($resumeInfo['otherinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【附加信息】' . PHP_EOL . $resumeInfo['otherinfo'];
        }

        $sql = 'UPDATE RpoResume SET school=?,major=?,degree=?,hasworkinfo=?,hasprojectinfo=?,haseducationinfo=?,updatedate=now() WHERE resumeid=?';
        $var = [$school, $major_code, $degree_code, $hasworkinfo, $hasprojectinfo, $haseducationinfo, $resumeId];
        Db::update($sql, $var);

        $sql = "UPDATE s_manager set company=?,school=?,major=?,degree=?,profile=?,isprofile=?,lastupdate=sysdate where UserID51job=? ";

        $profile = trim($profile);
        $isprofile = $profile == '' ? '0' : '1';
        $var_oracle = [$company, $school, $major_code, $degree_code, $profile, $isprofile, $resumeId];
        Db::connect('jyrpo_oracle')->update($sql, $var_oracle);

        //CaseResume表新增记录，需要将resumeid同步到es引擎
        $resumeUpdate = new ResumeUpdate();
        $resumeUpdate->addToQueue($resumeId);
    }

    /**
     * Notes:新增简历编辑日志
     * $oprId     操作人ID
     * $resumeId  简历ID
     * $type 类型：11-基本信息，12-求职意向，13-工作经历，14-项目经验，15-教育经历，16-附加信息，19-简历头像
     */
    public function addResumeEditLog($oprId, $resumeId, $type) {
        $insSql = 'INSERT INTO RpoResumeEditHis(oprid,resumeid,oprtype,createdate,updatedate) values (?,?,?,now(),now())';
        $insVar = [$oprId, $resumeId, $type];
        Db::insert($insSql, $insVar);

        //RpoResume表更新记录，需要将resumeid同步到es引擎
        $resumeUpdate = new ResumeUpdate();
        $resumeUpdate->addToQueue($resumeId);
    }

    /**
     * Notes:删除简历头像
     */
    public function delResumeHeadPic($oprId, $resumeId) {
        //检测简历是否是RPO简历
        $result = $this->getResumeBaseInfo($resumeId, 'headpath');
        if (empty($result)) {
            return ['status' => false, 'message' => '该简历ID不存在'];
        }
        $delStatus = true;
        if (!empty($result['headpath'])) {
            $delStatus = unlink(FILESERVER . '/' . $result['headpath']);
        }
        if (!$delStatus) {
            return ['status' => false, 'message' => '删除失败'];
        }
        $sql = 'UPDATE RpoResume SET headpath=?,updator=?,updatedate=now() WHERE resumeid=?';
        $var = ['', $oprId, $resumeId];

        $result = Db::update($sql, $var);

        if ($result == 1) {
            $editType = '19';
            $this->addResumeEditLog($oprId, $resumeId, $editType);
        }

        return [
            'status' => $result == 1,
            'message' => $result == 1 ? '删除成功' : '删除失败,请稍后再试'
        ];
    }


    /**
     * Notes:保存简历头像
     */
    public function saveResumeHeadPic($oprId, $resumeId, $headPath) {
        $sql = 'UPDATE RpoResume SET headpath=?,updator=?,updatedate=now() WHERE resumeid=?';
        $var = [$headPath, $oprId, $resumeId];

        $result = Db::update($sql, $var);

        if ($result == 1) {
            $editType = '19';
            $this->addResumeEditLog($oprId, $resumeId, $editType);
        }

        return [
            'status' => $result == 1,
            'message' => $result == 1 ? '保存成功' : '保存失败,请稍后再试'
        ];
    }

    public function &hideFields(&$resumeList, $params, $hasPlaceholders = false) {
        $hideField = function (&$resume, $paramNames, $fieldNames, $placeholder = '') use (&$params) {
            if (!is_array($paramNames)) {
                if (!is_string($paramNames)) return;
                $paramNames = preg_split('/\s*,\s*/u', $paramNames);
            }
            foreach ($paramNames as $paramName) {
                if (!empty($params[$paramName]) && $params[$paramName] == 1) return;
            }
            if (!is_array($fieldNames)) {
                if (!is_string($fieldNames)) return;
                $fieldNames = preg_split('/\s*,\s*/u', $fieldNames);
            }
            foreach ($fieldNames as $fieldName) {
                if (isset($resume[$fieldName]) && is_array($resume[$fieldName])) {
                    array_walk_recursive($resume[$fieldName], function (&$value) use (&$placeholder) {
                        if (!empty($value)) $value = $placeholder;
                    });
                } else {
                    if (!empty($resume[$fieldName])) $resume[$fieldName] = $placeholder;
                }
            }
        };
        $placeholder = $hasPlaceholders ? '******' : '';

//        $dimension = 2;
//        foreach ($resumeList as $key => $value) {
//            if (!is_array($value) && !is_numeric($key)) {
//                $dimension = 1;
//                break;
//            }
//        }
//        if ($dimension == 1) {
//            $loopResumeList = [&$resumeList];
//        } else {
        $loopResumeList =& $resumeList;
//        }
        foreach ($loopResumeList as &$resume) {
            $hideField($resume, ['param_cname', 'cname'], ['idcard', 'homepage'], $placeholder);
            $hideField($resume, ['param_cname', 'cname'], 'cname', "ID:" . $resume['resumeid']);
            $hideField($resume, ['param_phone', 'phone'], ['phone', 'email', 'address', 'othercontacts', 'idcard', 'homepage'], $placeholder);
            $hideField($resume, ['param_expectsalary', 'expectsalary'], ['expectsalary', 'expectsalaryinfo', 'expectAnnualSalary', 'expsalaryfrom', 'expsalaryto'], $placeholder);
            $hideField($resume, ['param_salary', 'salary'], ['salary', 'currentsalaryinfo', 'currentAnnualSalary', 'hascurrentsalary'], $placeholder);
            if ((empty($params['param_salary']) || $params['param_salary'] != 1) && !empty($resume['workinfo']) && is_array($resume['workinfo'])) {
                foreach ($resume['workinfo'] as &$item) {
                    if (!empty($item['salary'])) $item['salary'] = $placeholder;
                }
            }
            if ((empty($params['company']) || $params['company'] != 1) &&
                !empty($hideCompany = formatTolower(empty($resume['recentcompany']) ? ($resume['company'] ?? '') : $resume['recentcompany']))) {
                if (!empty($resume['recentcompany'])) $resume['recentcompany'] = '某公司';
                if (!empty($resume['company'])) $resume['company'] = '某公司';
                if (!empty($resume['workinfo']) && is_array($resume['workinfo'])) {
                    foreach ($resume['workinfo'] as &$item) {
                        if (formatToLower($item['company']) == $hideCompany) $item['company'] = '某公司';
                    }
                }
                if (!empty($resume['projectinfo']) && is_array($resume['projectinfo'])) {
                    foreach ($resume['projectinfo'] as &$item) {
                        if (formatToLower($item['company']) == $hideCompany) $item['company'] = '某公司';
                    }
                }
            }
            if ((empty($params['attach']) || $params['attach'] != 1)) {
                if (isset($resume['hasattachinfo'])) $resume['hasattachinfo'] = 0;
                if (isset($resume['attachment'])) $resume['attachment'] = [];
            }
        }
        return $resumeList;
    }

    public function hideNotDownloadedFields(&$resumes, $alreadyDownList, $resumeIdField = 'resumeid') {
//        $dimension = 2;
//        foreach ($resumes as $key => $value) {
//            if (!is_array($value) && !is_numeric($key)) {
//                $dimension = 1;
//                break;
//            }
//        }
//        if ($dimension == 1) {
//            $resumeList = [&$resumes];
//        } else {
        $resumeList =& $resumes;
//        }
        foreach ($resumeList as &$resume) {
            $resume['isdownload'] = 1;
            if (!in_array($resume[$resumeIdField], $alreadyDownList)) {
                if (isset($resume['cname'])) $resume['cname'] = "ID:" . $resume['resumeid'];
                if (!empty($resume['phone'])) $resume['phone'] = '***********';
                if (!empty($resume['email'])) $resume['email'] = '***********';
                if (!empty($resume['address'])) $resume['address'] = '***********';
                if (!empty($resume['othercontacts'])) $resume['othercontacts'] = '***********';
                $resume['isdownload'] = 0;
            }
        }
    }

    /**简历添加沟通记录
     * @param $caseId    职位id
     * @param $resumeId  简历id
     * @param $content   沟通记录 采用json格式存储
     * @return array
     * @throws Exception
     */
    public function addResumeContact($caseId, $resumeId, $content, $resumeRemark) {
        if (empty($caseId)) {
            return [
                'status' => false,
                'message' => '职位id不能为空'
            ];
        }
        if (empty($resumeId)) {
            return [
                'status' => false,
                'message' => '未选择简历'
            ];
        }
        if (empty($content)) {
            return [
                'status' => false,
                'message' => '未添加沟通记录'
            ];
        }
        if (strlen($resumeRemark) > 60000) {
            return [
                'status' => false,
                'message' => '沟通记录长度不能超过60000字符'
            ];
        }
        if (mb_strlen($resumeRemark) > 500 || mb_strlen($resumeRemark) < 3) {
            return [
                'status' => false,
                'message' => '评语需3至500字'
            ];
        }

        $sql = 'select subid from SCase where caseid = ? and status != ?';
        $var = [$caseId, '03'];
        $subId = Db::selectOne($sql, $var)['subid'];
        if (empty($subId)) {
            return [
                'status' => false,
                'message' => '职位不存在或已结束'
            ];
        }
        $oprInfo = UserAuth::getLoginInfo();
        $sql = 'select oprid from CaseOperator where caseid = ? and status = ?';
        $var = [$caseId, '01'];
        $caseOprIds = array_column(Db::select($sql, $var), 'oprid');
        if (!in_array($oprInfo['userid'], $caseOprIds)) {
            return [
                'status' => false,
                'message' => '非职位协作人，无操作权限'
            ];
        }
        //判断是否定义沟通表头
        $sql = 'select caseid from SCase where caseid = ? and hascontact = ?';
        $var = [$caseId, 1];
        $result = Db::selectOne($sql, $var);
        if (empty($result)) {
            return [
                'status' => false,
                'message' => '该职位尚未定义沟通表头'
            ];
        }

        //添加沟通记录
        $sql = 'select id,remarkid from ResumeContact where resumeid = ? and caseid = ? and status = ?';
        $var = [$resumeId, $caseId, '01'];
        $result = Db::selectOne($sql, $var);

        if (!empty($result)) { //如果已存在沟通记录则更新该记录
            $contactId = $result['id'];
            $remarkId = $result['remarkid'];
            $updateSql = 'update ResumeContact set content = ? , updater = ? , updatername = ? , updatedate = Now() where id = ?';
            $updateVar = [
                json_encode($content),
                $oprInfo['userid'],
                $oprInfo['cname'],
                $contactId
            ];
            $statement1 = Db::connect()->prepareStatement($updateSql, $updateVar);
            $updateSql = 'update ResumeRemark set content = ? ,updator = ?, updatedate = Now() where id = ? and status = ?';
            $updateVar = [$resumeRemark, $oprInfo['userid'], $remarkId, '01'];
            $statement2 = Db::connect()->prepareStatement($updateSql, $updateVar);
            $result = Db::connect()->prepareTransactionStatement(false, $statement1, $statement2)->execute();
        } else {  //如果该职位下的该简历尚未添加过沟通记录，则新增记录
            //查找分库位置
            $result = DbIndex::getDbIndex($subId);
            $dbId = $result['dbid'];
            $tableId = $result['tableid'];
            $sql = 'select keycode from CaseResume_' . $tableId . ' where resumeid = ? and caseid = ? and status = ?';
            $var = [$resumeId, $caseId, '01'];
            $keyCode = Db::connect('jyrpo_' . $dbId)->selectOne($sql, $var)['keycode'];
            if (empty($keyCode)) {
                return [
                    'status' => false,
                    'message' => '未找到该职位下对应简历'
                ];
            }

            $insertSql = 'insert into ResumeContact (id,resumeid,caseid,keycode,status,creater,creatername,updater,updatername,content,remarkid,createdate,updatedate)
                    values (?,?,?,?,?,?,?,?,?,?,?,Now(),Now())';
            $insertVar = [
                Uuid::uuid1()->toString(),
                $resumeId,
                $caseId,
                $keyCode,
                '01',
                $oprInfo['userid'],
                $oprInfo['cname'],
                $oprInfo['userid'],
                $oprInfo['cname'],
                json_encode($content),
                Uuid::uuid1()->toString(),
            ];
            $statement1 = Db::connect()->prepareStatement($insertSql, $insertVar);
            $contactId = $insertVar[0];
            $remarkId = $insertVar[10];

            $insertSql = 'insert into ResumeRemark (id,resumeid,content,creator,createdate,updator,updatedate,status,caseid,ContactId) 
                    values (?,?,?,?,Now(),?,Now(),?,?,?)';
            $insertVar = [
                $remarkId,
                $resumeId,
                $resumeRemark,
                $oprInfo['userid'],
                $oprInfo['userid'],
                '01',
                $caseId,
                $contactId
            ];
            $statement2 = Db::connect()->prepareStatement($insertSql, $insertVar);
            $result = Db::connect()->prepareTransactionStatement(false, $statement1, $statement2)->execute();
        }
        return [
            'status' => $result ? true : false,
            'message' => $result ? '添加成功' : '添加失败'
        ];
    }

    /**
     * 获取简历下沟通记录
     * @param $resumeId
     * @param $caseId
     * @return array
     */
    public function getResumeContact($resumeId, $caseId) {
        if (empty($caseId)) {
            return [
                'status' => false,
                'message' => '职位id不能为空'
            ];
        }
        if (empty($resumeId)) {
            return [
                'status' => false,
                'message' => '未选择简历'
            ];
        }
        $sql = 'select subid from SCase where caseid = ? and status != ?';
        $var = [$caseId, '03'];
        $subId = Db::selectOne($sql, $var)['subid'];
        if (empty($subId)) {
            return [
                'status' => false,
                'message' => '职位不存在或已结束'
            ];
        }
        $oprInfo = UserAuth::getLoginInfo();
        $sql = 'select oprid from CaseOperator where caseid = ? and status = ?';
        $var = [$caseId, '01'];
        $caseOprIds = array_column(Db::select($sql, $var), 'oprid');
        if (!in_array($oprInfo['userid'], $caseOprIds)) {
            return [
                'status' => false,
                'message' => '非职位协作人，无操作权限'
            ];
        }
        $sql = 'select rc.content as content , rr.content as remark from ResumeContact as rc left join ResumeRemark as rr on rc.remarkid=rr.id
                where rc.resumeid = ? and rc.caseid = ? and rc.status = ?';
        $var = [$resumeId, $caseId, '01'];
        $result = Db::selectOne($sql, $var);
        $resumeContactContent = $result['content'];
        $resumeRemark = $result['remark'];
        return [
            'status' => true,
            'message' => '获取成功',
            'content' => json_decode($resumeContactContent, true) ?? [],
            'remark' => $resumeRemark
        ];
    }

    /**
     * 对简历识别有误的简历进行反馈
     * @param $resumeID
     * @param $oprId
     * @param $reason
     * @return array
     */
    public function reportErrorResume($resumeId, $oprId, $reason) {
        if (mb_strlen($reason) > 100 || empty($reason)) {
            return [
                'status' => false,
                'message' => '文本长度需为1~100字'
            ];
        }
        $sql = 'select id from UploadResume where resumeid = ?';
        $var = [$resumeId];
        $result = Db::selectOne($sql, $var);
        if (empty($result)) {
            return [
                'status' => false,
                'message' => '简历不存在'
            ];
        }
        $sql = 'insert into CvReport (userid,resumeid,reason,updatedate) values(?,?,?,Now())';
        $var = [$oprId, $resumeId, $reason];
        $result = Db::insert($sql, $var);
        if (!$result) {
            Log::error('简历错误反馈写入数据库失败', ['resumeid' => $resumeId, 'reason' => $reason]);
            return [
                'status' => false,
                'message' => '反馈记录添加失败，请重试'
            ];
        }
        return [
            'status' => true,
            'message' => '反馈成功'
        ];
    }
}